diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2008-04-28 16:05:01 +0000 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2008-04-28 16:05:01 +0000 |
commit | b33c4447d073350c7291951dda75141effbde27a (patch) | |
tree | 50280d2f1f7d8dd00bc416518a477a7118ecd0de /patches/glibc-2.5 | |
parent | fc0965ea989129c522b10a117e82710c28f4c9a6 (diff) | |
download | OSELAS.Toolchain-b33c4447d073350c7291951dda75141effbde27a.tar.gz OSELAS.Toolchain-b33c4447d073350c7291951dda75141effbde27a.tar.xz |
git-svn-id: https://svn.pengutronix.de/svn/oselas/toolchain/branches/OSELAS.Toolchain-mkl@6243 f8d472c7-5700-0410-ac5a-87979cec3adf
Diffstat (limited to 'patches/glibc-2.5')
27 files changed, 16903 insertions, 323 deletions
diff --git a/patches/glibc-2.5/generic/configure-sane_readelf.diff b/patches/glibc-2.5/generic/configure-sane_readelf.diff index cba2b8f..83f79b0 100644 --- a/patches/glibc-2.5/generic/configure-sane_readelf.diff +++ b/patches/glibc-2.5/generic/configure-sane_readelf.diff @@ -1,8 +1,12 @@ +--- + configure | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 88 insertions(+), 2 deletions(-) + Index: glibc-2.5/configure =================================================================== ---- glibc-2.5.orig/configure 2008-03-08 10:28:18.000000000 +0100 -+++ glibc-2.5/configure 2008-03-08 10:28:31.000000000 +0100 -@@ -5491,6 +5491,92 @@ +--- glibc-2.5.orig/configure ++++ glibc-2.5/configure +@@ -5488,6 +5488,92 @@ _ACEOF fi fi @@ -95,7 +99,7 @@ Index: glibc-2.5/configure echo "$as_me:$LINENO: checking for .preinit_array/.init_array/.fini_array support" >&5 echo $ECHO_N "checking for .preinit_array/.init_array/.fini_array support... $ECHO_C" >&6 if test "${libc_cv_initfini_array+set}" = set; then -@@ -5510,7 +5596,7 @@ +@@ -5507,7 +5593,7 @@ EOF echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } then @@ -104,7 +108,7 @@ Index: glibc-2.5/configure libc_cv_initfini_array=yes else libc_cv_initfini_array=no -@@ -5804,7 +5890,7 @@ +@@ -5801,7 +5887,7 @@ EOF echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } then diff --git a/patches/glibc-2.5/generic/configure_in-sane_readelf.diff b/patches/glibc-2.5/generic/configure_in-sane_readelf.diff index 144bb22..116938c 100644 --- a/patches/glibc-2.5/generic/configure_in-sane_readelf.diff +++ b/patches/glibc-2.5/generic/configure_in-sane_readelf.diff @@ -1,8 +1,12 @@ +--- + configure.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + Index: glibc-2.5/configure.in =================================================================== ---- glibc-2.5.orig/configure.in 2008-03-08 10:27:55.000000000 +0100 -+++ glibc-2.5/configure.in 2008-03-08 10:28:24.000000000 +0100 -@@ -1353,6 +1353,8 @@ +--- glibc-2.5.orig/configure.in ++++ glibc-2.5/configure.in +@@ -1350,6 +1350,8 @@ EOF fi fi @@ -11,7 +15,7 @@ Index: glibc-2.5/configure.in AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support, libc_cv_initfini_array, [dnl cat > conftest.c <<EOF -@@ -1364,7 +1366,7 @@ +@@ -1361,7 +1363,7 @@ EOF if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD]) then @@ -20,7 +24,7 @@ Index: glibc-2.5/configure.in libc_cv_initfini_array=yes else libc_cv_initfini_array=no -@@ -1546,7 +1548,7 @@ +@@ -1543,7 +1545,7 @@ dnl cross-platform since the gcc used ca dnl introducing new options this is not easily doable. Instead use a tool dnl which always is cross-platform: readelf. To detect whether -z combreloc dnl look for a section named .rel.dyn. diff --git a/patches/glibc-2.5/generic/cross_timezone.diff b/patches/glibc-2.5/generic/cross_timezone.diff index bc743fc..62a6f11 100644 --- a/patches/glibc-2.5/generic/cross_timezone.diff +++ b/patches/glibc-2.5/generic/cross_timezone.diff @@ -12,7 +12,7 @@ Description: Adds native compile support to the build system then uses that the target. --- - Makeconfig | 14 ++++++++++++++ + Makeconfig | 12 ++++++++++++ Makerules | 9 ++++++++- Rules | 9 ++++++++- iconv/Makefile | 4 ++++ @@ -29,13 +29,128 @@ Description: Adds native compile support to the build system then uses that malloc/Makefile | 5 ----- sunrpc/Makefile | 23 ++++++++++++++++++----- timezone/Makefile | 14 ++++++++++---- - 17 files changed, 120 insertions(+), 24 deletions(-) + 17 files changed, 118 insertions(+), 24 deletions(-) -Index: iconv/Makefile +Index: glibc-2.5/Makeconfig =================================================================== ---- iconv/Makefile.orig 2008-03-08 10:27:55.000000000 +0100 -+++ iconv/Makefile 2008-03-08 10:28:36.000000000 +0100 -@@ -56,6 +56,9 @@ +--- glibc-2.5.orig/Makeconfig ++++ glibc-2.5/Makeconfig +@@ -447,6 +447,13 @@ ifndef +link-static + $(common-objpfx)libc% $(+postinit),$^) \ + $(link-extra-libs-static) $(link-libc-static) $(+postctor) $(+postinit) + endif ++# Command for linking programs against the host system. ++ifndef +link-native +++link-native = $(BUILD_CC) -static -g -o $@ $^ \ ++ $(LDFLAGS) $(LDFLAGS-$(@F)) \ ++ $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ ++ $(link-extra-libs) ++endif + # Command for statically linking bounded-pointer programs with the C library. + ifndef +link-bounded + +link-bounded = $(CC) -nostdlib -nostartfiles -static -fbounded-pointers -o $@ \ +@@ -660,6 +667,8 @@ endif # $(+cflags) == "" + $(+sysdep-includes) $(includes) \ + $(patsubst %/,-I%,$(..)) $(libio-include) -I. $(sysincludes) + +++includes-native = -I$(..)include-native -I$(objpfx) -I. ++ + # Since libio has several internal header files, we use a -I instead + # of many little headers in the include directory. + libio-include = -I$(..)libio +@@ -675,6 +684,9 @@ CPPFLAGS = $($(subdir)-CPPFLAGS) $(+incl + $(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \ + $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F))) + CPPFLAGS += $(CPPFLAGS-config) ++CPPFLAGS-native = -D_GNU_SOURCE $($(subdir)-CPPFLAGS) $(+includes-native) $(defines) \ ++ $(CPPFLAGS-$(suffix $@)) -include $(..)include/libc-symbols.h \ ++ $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F))) + override CFLAGS = -std=gnu99 \ + $(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \ + $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \ +Index: glibc-2.5/Makerules +=================================================================== +--- glibc-2.5.orig/Makerules ++++ glibc-2.5/Makerules +@@ -292,6 +292,9 @@ endef + object-suffixes-left := $(all-object-suffixes) + include $(o-iterator) + ++$(objpfx)%-native.o: %.c $(before-compile) ++ $(native-compile-command.c) ++ + # Omit the objpfx rules when building in the source tree, because + # objpfx is empty and so these rules just override the ones above. + ifdef objpfx +@@ -368,6 +371,8 @@ compile-command.S = $(compile.S) $(OUTPU + compile-command.s = $(COMPILE.s) $< $(OUTPUT_OPTION) $(compile-mkdep-flags) + compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags) + compile-command.cc = $(compile.cc) $(OUTPUT_OPTION) $(compile-mkdep-flags) ++# Native commands ++native-compile-command.c = $(native-compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags) + + # GCC can grok options after the file name, and it looks nicer that way. + compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS) +@@ -377,6 +382,8 @@ compile.S = $(CC) $< -c $(CPPFLAGS) $(S- + COMPILE.S = $(CC) -c $(CPPFLAGS) $(S-CPPFLAGS) \ + $(ASFLAGS) $(ASFLAGS-$(suffix $@)) + COMPILE.s = $(filter-out -pipe,$(CC)) -c $(ASFLAGS) ++# Native commands ++native-compile.c = $(BUILD_CC) -g $< -c $(CFLAGS-native) $(CPPFLAGS-native) + + # We need this for the output to go in the right place. It will default to + # empty if make was configured to work with a cc that can't grok -c and -o +@@ -1176,7 +1183,7 @@ define native-compile + $(make-target-directory) + $(patsubst %/,cd % &&,$(objpfx)) \ + $(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \ +- $(firstword $(filter /%,$< $(shell pwd)/$<)) -o $(@F) ++ $(addprefix $(shell pwd)/, $^) -o $(@F) + endef + + # Command to compile $< in $(common-objdir) using the native libraries. +Index: glibc-2.5/Rules +=================================================================== +--- glibc-2.5.orig/Rules ++++ glibc-2.5/Rules +@@ -87,7 +87,7 @@ common-generated += dummy.o dummy.c + + .PHONY: others tests + ifeq ($(build-programs),yes) +-others: $(addprefix $(objpfx),$(others) $(sysdep-others) $(extra-objs)) ++others: $(addprefix $(objpfx),$(others) $(others-native) $(sysdep-others) $(extra-objs)) + else + others: $(addprefix $(objpfx),$(extra-objs)) + endif +@@ -106,9 +106,11 @@ endif + ifeq ($(build-programs),yes) + binaries-all = $(others) $(sysdep-others) $(tests) $(xtests) $(test-srcs) + binaries-static = $(others-static) $(tests-static) $(xtests-static) ++binaries-native = $(others-native) + else + binaries-all = $(tests) $(xtests) $(test-srcs) + binaries-static = ++binaries-native = + endif + + binaries-shared = $(filter-out $(binaries-static), $(binaries-all)) +@@ -127,6 +129,11 @@ $(addprefix $(objpfx),$(binaries-static) + $(+link-static) + endif + ++ifneq "$(strip $(binaries-native))" "" ++$(addprefix $(objpfx),$(binaries-native)): %: %.o ++ $(+link-native) ++endif ++ + ifeq ($(build-bounded),yes) + binaries-bounded = $(addsuffix -bp,$(tests) $(xtests) $(test-srcs)) + $(addprefix $(objpfx),$(binaries-bounded)): %-bp: %.ob \ +Index: glibc-2.5/iconv/Makefile +=================================================================== +--- glibc-2.5.orig/iconv/Makefile ++++ glibc-2.5/iconv/Makefile +@@ -56,6 +56,9 @@ distribute = gconv_builtin.h gconv_int.h iconvconfig.h others = iconv_prog iconvconfig @@ -45,47 +160,85 @@ Index: iconv/Makefile install-others = $(inst_bindir)/iconv install-sbin = iconvconfig -@@ -78,6 +81,7 @@ +@@ -78,6 +81,7 @@ $(inst_bindir)/iconv: $(objpfx)iconv_pro $(objpfx)iconv_prog: $(iconv_prog-modules:%=$(objpfx)%.o) $(objpfx)iconvconfig: $(iconvconfig-modules:%=$(objpfx)%.o) +$(objpfx)iconvconfig-native: $(iconvconfig-modules:%=$(objpfx)%-native.o) - # eglibc: ifneq ($(cross-compiling),yes) + ifneq ($(cross-compiling),yes) xtests: test-iconvconfig -Index: include-native/bits/libc-tsd.h +Index: glibc-2.5/iconvdata/Makefile +=================================================================== +--- glibc-2.5.orig/iconvdata/Makefile ++++ glibc-2.5/iconvdata/Makefile +@@ -311,23 +311,25 @@ $(objpfx)iso8859-7jp.stmp: $(charmaps)/I + + headers: $(addprefix $(objpfx), $(generated-modules:=.h)) + ++ifeq ($(cross-compiling),no) ++iconvconfig-cmd = LC_ALL=C LANGUAGE=C \ ++ $(common-objpfx)elf/ld.so --library-path $(rpath-link) \ ++ $(common-objpfx)iconv/iconvconfig ++else ++iconvconfig-cmd = LC_ALL=C LANGUAGE=C \ ++ $(common-objpfx)iconv/iconvconfig-native ++endif ++ + $(addprefix $(inst_gconvdir)/, $(modules.so)): \ + $(inst_gconvdir)/%: $(objpfx)% $(+force) + $(do-install-program) + $(inst_gconvdir)/gconv-modules: gconv-modules $(+force) + $(do-install) +-ifeq (no,$(cross-compiling)) + # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary + # if this libc has more gconv modules than the previously installed one. + if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \ +- LC_ALL=C LANGUAGE=C \ +- $(common-objpfx)elf/ld.so --library-path $(rpath-link) \ +- $(common-objpfx)iconv/iconvconfig \ +- $(addprefix --prefix=,$(install_root)); \ ++ $(iconvconfig-cmd) $(addprefix --prefix=,$(install_root)); \ + fi +-else +- @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache' +-endif + + endif # build-shared = yes + +Index: glibc-2.5/include-native/bits/libc-tsd.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/bits/libc-tsd.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/bits/libc-tsd.h @@ -0,0 +1,3 @@ +#ifndef __libc_tsd_define +#define __libc_tsd_define(A,B) +#endif -Index: include-native/config.h +Index: glibc-2.5/include-native/config.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/config.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/config.h @@ -0,0 +1 @@ +/* Empty */ -Index: include-native/gnu/stubs.h +Index: glibc-2.5/include-native/gnu/stubs.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/gnu/stubs.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/gnu/stubs.h @@ -0,0 +1 @@ +/* Empty */ -Index: include-native/intl/loadinfo.h +Index: glibc-2.5/include-native/intl/loadinfo.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/intl/loadinfo.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/intl/loadinfo.h @@ -0,0 +1,4 @@ +#ifndef LOADINFO_H +#define LOADINFO_H +struct loaded_l10nfile; +#endif -Index: include-native/libintl.h +Index: glibc-2.5/include-native/libintl.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/libintl.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/libintl.h @@ -0,0 +1,13 @@ +#include_next <libintl.h> + @@ -100,16 +253,16 @@ Index: include-native/libintl.h +#ifndef _libc_intl_domainname +#define _libc_intl_domainname "libc" +#endif -Index: include-native/symbol-hacks.h +Index: glibc-2.5/include-native/symbol-hacks.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/symbol-hacks.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/symbol-hacks.h @@ -0,0 +1 @@ +/* Empty */ -Index: include-native/tls.h +Index: glibc-2.5/include-native/tls.h =================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ include-native/tls.h 2008-03-08 10:28:36.000000000 +0100 +--- /dev/null ++++ glibc-2.5/include-native/tls.h @@ -0,0 +1,11 @@ +#ifndef _include_tls_h +#define _include_tls_h 1 @@ -122,11 +275,11 @@ Index: include-native/tls.h +#endif + +#endif -Index: locale/Makefile +Index: glibc-2.5/locale/Makefile =================================================================== ---- locale/Makefile.orig 2008-03-08 10:27:41.000000000 +0100 -+++ locale/Makefile 2008-03-08 10:28:36.000000000 +0100 -@@ -44,6 +44,9 @@ +--- glibc-2.5.orig/locale/Makefile ++++ glibc-2.5/locale/Makefile +@@ -44,6 +44,9 @@ categories = ctype messages monetary num aux = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \ xlocale localename global-locale coll-lookup others = localedef locale @@ -136,7 +289,7 @@ Index: locale/Makefile #others-static = localedef locale install-bin = localedef locale extra-objs = $(localedef-modules:=.o) $(localedef-aux:=.o) \ -@@ -81,6 +84,12 @@ +@@ -81,6 +84,12 @@ $(objpfx)localedef: $(localedef-aux:%=$( $(objpfx)locale: $(locale-modules:%=$(objpfx)%.o) $(objpfx)localedef $(objpfx)locale: $(lib-modules:%=$(objpfx)%.o) @@ -149,11 +302,11 @@ Index: locale/Makefile C-translit.h: C-translit.h.in gen-translit.pl $(PERL) gen-translit.pl < $< > $@.tmp mv -f $@.tmp $@ -Index: localedata/Makefile +Index: glibc-2.5/localedata/Makefile =================================================================== ---- localedata/Makefile.orig 2008-03-08 10:27:55.000000000 +0100 -+++ localedata/Makefile 2008-03-08 10:28:36.000000000 +0100 -@@ -226,8 +226,13 @@ +--- glibc-2.5.orig/localedata/Makefile ++++ glibc-2.5/localedata/Makefile +@@ -206,8 +206,13 @@ include SUPPORTED INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES)) # Sometimes the whole collection of locale files should be installed. @@ -167,95 +320,11 @@ Index: localedata/Makefile install-locales: $(INSTALL-SUPPORTED-LOCALES) install-locales-dir: -Index: Makeconfig -=================================================================== ---- Makeconfig.orig 2008-03-08 10:27:55.000000000 +0100 -+++ Makeconfig 2008-03-08 10:28:36.000000000 +0100 -@@ -447,6 +447,13 @@ - $(common-objpfx)libc% $(+postinit),$^) \ - $(link-extra-libs-static) $(link-libc-static) $(+postctor) $(+postinit) - endif -+# Command for linking programs against the host system. -+ifndef +link-native -++link-native = $(BUILD_CC) -static -g -o $@ $^ \ -+ $(LDFLAGS) $(LDFLAGS-$(@F)) \ -+ $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ -+ $(link-extra-libs) -+endif - # Command for statically linking bounded-pointer programs with the C library. - ifndef +link-bounded - +link-bounded = $(CC) -nostdlib -nostartfiles -static -fbounded-pointers -o $@ \ -@@ -668,6 +675,8 @@ - $(+sysdep-includes) $(includes) \ - $(patsubst %/,-I%,$(..)) $(libio-include) -I. $(sysincludes) - -++includes-native = -I$(..)include-native -I$(objpfx) -I. -+ - # Since libio has several internal header files, we use a -I instead - # of many little headers in the include directory. - libio-include = -I$(..)libio -@@ -682,10 +691,15 @@ - $(foreach lib,$(libof-$(basename $(@F))) \ - $(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \ - $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F))) -+CPPFLAGS-native = -D_GNU_SOURCE $($(subdir)-CPPFLAGS) $(+includes-native) $(defines) \ -+ $(CPPFLAGS-$(suffix $@)) -include $(..)include/libc-symbols.h \ -+ $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F))) - override CFLAGS = -std=gnu99 \ - $(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \ - $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \ - $(CFLAGS-$(@F)) -+override CFLAGS-native = -std=gnu99 $(default_cflags) $(+gccwarn-c) \ -+ $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) $(CFLAGS-$(@F)) - override CXXFLAGS = $(c++-sysincludes) \ - $(filter-out %frame-pointer,$(+cflags)) $(sysdep-CFLAGS) \ - $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) $(CFLAGS-$(@F)) -Index: Makerules -=================================================================== ---- Makerules.orig 2008-03-08 10:27:59.000000000 +0100 -+++ Makerules 2008-03-08 10:28:36.000000000 +0100 -@@ -292,6 +292,9 @@ - object-suffixes-left := $(all-object-suffixes) - include $(o-iterator) - -+$(objpfx)%-native.o: %.c $(before-compile) -+ $(native-compile-command.c) -+ - # Omit the objpfx rules when building in the source tree, because - # objpfx is empty and so these rules just override the ones above. - ifdef objpfx -@@ -368,6 +371,8 @@ - compile-command.s = $(COMPILE.s) $< $(OUTPUT_OPTION) $(compile-mkdep-flags) - compile-command.c = $(compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags) - compile-command.cc = $(compile.cc) $(OUTPUT_OPTION) $(compile-mkdep-flags) -+# Native commands -+native-compile-command.c = $(native-compile.c) $(OUTPUT_OPTION) $(compile-mkdep-flags) - - # GCC can grok options after the file name, and it looks nicer that way. - compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS) -@@ -377,6 +382,8 @@ - COMPILE.S = $(CC) -c $(CPPFLAGS) $(S-CPPFLAGS) \ - $(ASFLAGS) $(ASFLAGS-$(suffix $@)) - COMPILE.s = $(filter-out -pipe,$(CC)) -c $(ASFLAGS) -+# Native commands -+native-compile.c = $(BUILD_CC) -g $< -c $(CFLAGS-native) $(CPPFLAGS-native) - - # We need this for the output to go in the right place. It will default to - # empty if make was configured to work with a cc that can't grok -c and -o -@@ -1187,7 +1194,7 @@ - $(make-target-directory) - $(patsubst %/,cd % &&,$(objpfx)) \ - $(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \ -- $(firstword $(filter /%,$< $(shell pwd)/$<)) -o $(@F) -+ $(addprefix $(shell pwd)/, $^) -o $(@F) - endef - - # Command to compile $< in $(common-objdir) using the native libraries. -Index: malloc/Makefile +Index: glibc-2.5/malloc/Makefile =================================================================== ---- malloc/Makefile.orig 2008-03-08 10:27:55.000000000 +0100 -+++ malloc/Makefile 2008-03-08 10:28:36.000000000 +0100 -@@ -73,10 +73,6 @@ +--- glibc-2.5.orig/malloc/Makefile ++++ glibc-2.5/malloc/Makefile +@@ -73,10 +73,6 @@ address-width=18 endif endif @@ -266,7 +335,7 @@ Index: malloc/Makefile # If the gd library is available we build the `memusagestat' program. ifneq ($(LIBGD),no) others: $(objpfx)memusage -@@ -91,7 +87,6 @@ +@@ -91,7 +87,6 @@ extra-objs += memusagestat.o # is to presume that the standard system headers will be ok for this file. $(objpfx)memusagestat.o: sysincludes = # nothing endif @@ -274,48 +343,11 @@ Index: malloc/Makefile # Another goal which can be used to override the configure decision. .PHONY: do-memusagestat -Index: Rules +Index: glibc-2.5/sunrpc/Makefile =================================================================== ---- Rules.orig 2008-03-08 10:27:56.000000000 +0100 -+++ Rules 2008-03-08 10:28:36.000000000 +0100 -@@ -87,7 +87,7 @@ - - .PHONY: others tests - ifeq ($(build-programs),yes) --others: $(addprefix $(objpfx),$(others) $(sysdep-others) $(extra-objs)) -+others: $(addprefix $(objpfx),$(others) $(others-native) $(sysdep-others) $(extra-objs)) - else - others: $(addprefix $(objpfx),$(extra-objs)) - endif -@@ -106,9 +106,11 @@ - ifeq ($(build-programs),yes) - binaries-all = $(others) $(sysdep-others) $(tests) $(xtests) $(test-srcs) - binaries-static = $(others-static) $(tests-static) $(xtests-static) -+binaries-native = $(others-native) - else - binaries-all = $(tests) $(xtests) $(test-srcs) - binaries-static = -+binaries-native = - endif - - binaries-shared = $(filter-out $(binaries-static), $(binaries-all)) -@@ -127,6 +129,11 @@ - $(+link-static) - endif - -+ifneq "$(strip $(binaries-native))" "" -+$(addprefix $(objpfx),$(binaries-native)): %: %.o -+ $(+link-native) -+endif -+ - ifeq ($(build-bounded),yes) - binaries-bounded = $(addsuffix -bp,$(tests) $(xtests) $(test-srcs)) - $(addprefix $(objpfx),$(binaries-bounded)): %-bp: %.ob \ -Index: sunrpc/Makefile -=================================================================== ---- sunrpc/Makefile.orig 2008-03-08 10:27:56.000000000 +0100 -+++ sunrpc/Makefile 2008-03-08 10:28:36.000000000 +0100 -@@ -70,6 +70,9 @@ +--- glibc-2.5.orig/sunrpc/Makefile ++++ glibc-2.5/sunrpc/Makefile +@@ -70,6 +70,9 @@ routines := auth_none auth_unix authuxpr clnt_unix svc_unix create_xid xdr_intXX_t others := rpcinfo @@ -325,16 +357,12 @@ Index: sunrpc/Makefile install-bin := rpcgen install-sbin := rpcinfo rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ -@@ -98,17 +101,17 @@ +@@ -98,15 +101,12 @@ otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libresolv.a endif -ifeq (no,$(cross-compiling)) --ifneq (yes,$(install-bootstrap-headers)) -# We can only build this library if we can run the rpcgen we build. -+#ifeq (no,$(cross-compiling)) -+#ifneq (yes,$(install-bootstrap-headers)) -+## We can only build this library if we can run the rpcgen we build. headers += $(rpcsvc:%.x=rpcsvc/%.h) extra-libs := librpcsvc extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass. @@ -342,13 +370,10 @@ Index: sunrpc/Makefile librpcsvc-inhibit-o = .os # Build no shared rpcsvc library. omit-deps = $(librpcsvc-routines) -endif --endif -+#endif -+#endif CFLAGS-xbootparam_prot.c = -Wno-unused $(PIC-ccflag) CFLAGS-xnlm_prot.c = -Wno-unused $(PIC-ccflag) -@@ -138,13 +141,26 @@ +@@ -136,13 +136,26 @@ $(objpfx)rpcgen: $(addprefix $(objpfx),$ $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) $(+link) @@ -375,7 +400,7 @@ Index: sunrpc/Makefile # Install the rpc data base file. $(inst_sysconfdir)/rpc: etc.rpc $(+force) -@@ -155,7 +171,7 @@ +@@ -153,7 +166,7 @@ $(inst_sysconfdir)/rpc: etc.rpc $(+force # relinked. $(rpcsvc:%.x=$(objpfx)rpcsvc/%.h): $(objpfx)rpcsvc/%.h: $(objpfx)rpcsvc/%.stmp @: @@ -384,7 +409,7 @@ Index: sunrpc/Makefile $(make-target-directory) -@rm -f ${@:stmp=T} $@ $(rpcgen-cmd) -h $< -o ${@:stmp=T} -@@ -165,7 +181,7 @@ +@@ -163,7 +176,7 @@ $(objpfx)rpcsvc/%.stmp: rpcsvc/%.x $(obj # Generate the rpcsvc XDR functions with rpcgen. $(rpcsvc:%.x=$(objpfx)x%.c): $(objpfx)x%.c: $(objpfx)x%.stmp @: @@ -393,11 +418,11 @@ Index: sunrpc/Makefile -@rm -f ${@:stmp=T} $@ $(rpcgen-cmd) -c $< -o ${@:stmp=T} $(move-if-change) $(@:stmp=T) $(@:stmp=c) -Index: timezone/Makefile +Index: glibc-2.5/timezone/Makefile =================================================================== ---- timezone/Makefile.orig 2008-03-08 10:27:41.000000000 +0100 -+++ timezone/Makefile 2008-03-08 10:28:36.000000000 +0100 -@@ -28,6 +28,9 @@ +--- glibc-2.5.orig/timezone/Makefile ++++ glibc-2.5/timezone/Makefile +@@ -28,6 +28,9 @@ distribute := tzfile.h private.h scheck. extra-objs := scheck.o ialloc.o others := zdump zic @@ -407,7 +432,7 @@ Index: timezone/Makefile tests := test-tz tst-timezone tzbases := africa antarctica asia australasia europe northamerica \ -@@ -69,13 +72,10 @@ +@@ -69,13 +72,10 @@ installed-posixrules-file := $(firstword $(addprefix $(inst_zonedir)/, \ $(posixrules-file))) @@ -421,7 +446,7 @@ Index: timezone/Makefile ifeq ($(have-ksh),yes) install-others += $(inst_zonedir)/iso3166.tab $(inst_zonedir)/zone.tab -@@ -128,7 +128,11 @@ +@@ -128,7 +128,11 @@ echo-zonenames: # We have to use `-d $(inst_zonedir)' to explictly tell zic where to # place the output files although $(zonedir) is compiled in. But the # user might have set $(install_root) on the command line of `make install'. @@ -433,7 +458,7 @@ Index: timezone/Makefile tzcompile = $(zic-cmd)$(target-zone-flavor) -L $(word 3,$^) \ -y $(dir $(word 4,$^))$(notdir $(word 4,$^)) $< -@@ -158,8 +162,10 @@ +@@ -158,8 +162,10 @@ $(installed-posixrules-file): $(inst_zon $(zic-cmd) -p $(posixrules) endif diff --git a/patches/glibc-2.5/generic/gentoo/0030_all_glibc-respect-env-CPPFLAGS.patch b/patches/glibc-2.5/generic/gentoo/0030_all_glibc-respect-env-CPPFLAGS.patch new file mode 100644 index 0000000..a36112f --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/0030_all_glibc-respect-env-CPPFLAGS.patch @@ -0,0 +1,32 @@ +Respect environment CPPFLAGS when we run ./configure so we can inject +random -D things without having to set CFLAGS/ASFLAGS + +--- + Makeconfig | 1 + + config.make.in | 1 + + 2 files changed, 2 insertions(+) + +Index: glibc-2.5/Makeconfig +=================================================================== +--- glibc-2.5.orig/Makeconfig ++++ glibc-2.5/Makeconfig +@@ -674,6 +674,7 @@ CPPFLAGS = $($(subdir)-CPPFLAGS) $(+incl + $(foreach lib,$(libof-$(basename $(@F))) \ + $(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \ + $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F))) ++CPPFLAGS += $(CPPFLAGS-config) + override CFLAGS = -std=gnu99 \ + $(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \ + $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \ +Index: glibc-2.5/config.make.in +=================================================================== +--- glibc-2.5.orig/config.make.in ++++ glibc-2.5/config.make.in +@@ -100,6 +100,7 @@ CC = @CC@ + CXX = @CXX@ + BUILD_CC = @BUILD_CC@ + CFLAGS = @CFLAGS@ ++CPPFLAGS-config = @CPPFLAGS@ + ASFLAGS-config = @ASFLAGS_config@ + AR = @AR@ + RANLIB = @RANLIB@ diff --git a/patches/glibc-2.5/generic/gentoo/1010_all_glibc-cvs-update-MINOR.patch b/patches/glibc-2.5/generic/gentoo/1010_all_glibc-cvs-update-MINOR.patch new file mode 100644 index 0000000..2b88ed2 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1010_all_glibc-cvs-update-MINOR.patch @@ -0,0 +1,21 @@ +2006-10-06 Andreas Jaeger <aj@suse.de> + + * include/features.h (__GLIBC_MINOR__): It's glibc 2.5 now. + +--- + include/features.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: glibc-2.5/include/features.h +=================================================================== +--- glibc-2.5.orig/include/features.h ++++ glibc-2.5/include/features.h +@@ -304,7 +304,7 @@ + /* Major and minor version number of the GNU C library package. Use + these macros to test for features in specific releases. */ + #define __GLIBC__ 2 +-#define __GLIBC_MINOR__ 4 ++#define __GLIBC_MINOR__ 5 + + #define __GLIBC_PREREQ(maj, min) \ + ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min)) diff --git a/patches/glibc-2.5/generic/gentoo/1015_all_glibc-2.5-realloc-assert.patch b/patches/glibc-2.5/generic/gentoo/1015_all_glibc-2.5-realloc-assert.patch new file mode 100644 index 0000000..2fd543a --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1015_all_glibc-2.5-realloc-assert.patch @@ -0,0 +1,29 @@ +http://sourceware.org/bugzilla/show_bug.cgi?id=3352 +http://bugs.gentoo.org/155255 + +--- + elf/dl-minimal.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +Index: glibc-2.5/elf/dl-minimal.c +=================================================================== +--- glibc-2.5.orig/elf/dl-minimal.c ++++ glibc-2.5/elf/dl-minimal.c +@@ -128,14 +128,13 @@ free (void *ptr) + void * weak_function + realloc (void *ptr, size_t n) + { +- void *new; + if (ptr == NULL) + return malloc (n); + assert (ptr == alloc_last_block); ++ size_t old_size = alloc_ptr - alloc_last_block; + alloc_ptr = alloc_last_block; +- new = malloc (n); +- assert (new == ptr); +- return new; ++ void *new = malloc (n); ++ return new != ptr ? memcpy (new, ptr, old_size) : new; + } + + /* Avoid signal frobnication in setjmp/longjmp. Keeps things smaller. */ diff --git a/patches/glibc-2.5/generic/gentoo/1025_all_glibc-2.5-getusershell-fixes.patch b/patches/glibc-2.5/generic/gentoo/1025_all_glibc-2.5-getusershell-fixes.patch new file mode 100644 index 0000000..152377e --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1025_all_glibc-2.5-getusershell-fixes.patch @@ -0,0 +1,55 @@ +http://bugs.gentoo.org/178758 +http://sourceware.org/ml/libc-hacker/2006-12/msg00009.html + +2006-12-09 Jakub Jelinek <jakub@redhat.com> + + * misc/getusershell.c (initshells): Check for integer overflows. + Make strings buffer one bigger as fgets always succeeds when second + argument is 1. Don't use calloc for shells array. Disallow + / as shell. + +--- + misc/getusershell.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +Index: glibc-2.5/misc/getusershell.c +=================================================================== +--- glibc-2.5.orig/misc/getusershell.c ++++ glibc-2.5/misc/getusershell.c +@@ -98,7 +98,7 @@ initshells() + register char **sp, *cp; + register FILE *fp; + struct stat64 statb; +- int flen; ++ size_t flen; + + free(shells); + shells = NULL; +@@ -114,9 +114,11 @@ initshells() + okshells[1] = _PATH_CSHELL; + return (char **) okshells; + } +- if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) ++ if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3) + goto init_okshells; +- shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); ++ if ((strings = malloc(statb.st_size + 2)) == NULL) ++ goto init_okshells; ++ shells = malloc(statb.st_size / 3 * sizeof (char *)); + if (shells == NULL) { + free(strings); + strings = NULL; +@@ -124,11 +126,11 @@ initshells() + } + sp = shells; + cp = strings; +- flen = statb.st_size; ++ flen = statb.st_size + 2; + while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) { + while (*cp != '#' && *cp != '/' && *cp != '\0') + cp++; +- if (*cp == '#' || *cp == '\0') ++ if (*cp == '#' || *cp == '\0' || cp[1] == '\0') + continue; + *sp++ = cp; + while (!isspace(*cp) && *cp != '#' && *cp != '\0') diff --git a/patches/glibc-2.5/generic/gentoo/1035_all_glibc-cvs-fix-fork-handler-refcount-in-child.patch b/patches/glibc-2.5/generic/gentoo/1035_all_glibc-cvs-fix-fork-handler-refcount-in-child.patch new file mode 100644 index 0000000..9b999d3 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1035_all_glibc-cvs-fix-fork-handler-refcount-in-child.patch @@ -0,0 +1,31 @@ +http://sourceware.org/ml/libc-alpha/2007-02/msg00025.html + +nptl/sysdeps/unix/sysv/linux/fork.c : __libc_fork() + +Reset the refcntr for the fork-handlers in the child process to 1. + + The refcntr may have been bumped up by the *OTHER* thread(s) doing a fork() in the parent process. This would leave the child with an incorrect refcntr for the fork-handlers leading us to wait for non-existing threads to drop the refcntr while doing __unregister_atfork(). Since there is only one thread in the child process, we reset it to 1, to reflect the actual count. + +--- + nptl/sysdeps/unix/sysv/linux/fork.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +Index: glibc-2.5/nptl/sysdeps/unix/sysv/linux/fork.c +=================================================================== +--- glibc-2.5.orig/nptl/sysdeps/unix/sysv/linux/fork.c ++++ glibc-2.5/nptl/sysdeps/unix/sysv/linux/fork.c +@@ -167,8 +167,12 @@ __libc_fork (void) + allp->handler->child_handler (); + + /* Note that we do not have to wake any possible waiter. +- This is the only thread in the new process. */ +- --allp->handler->refcntr; ++ This is the only thread in the new process. ++ The count may have been bumped up by the other threads in ++ the parent, doing a fork. We reset it to 1, to avoid waiting ++ for non-existing thread(s) to release the count. ++ */ ++ allp->handler->refcntr = 1; + + /* XXX We could at this point look through the object pool + and mark all objects not on the __fork_handlers list as diff --git a/patches/glibc-2.5/generic/gentoo/1050_all_glibc-fix-printf-overflow-with-large-precisions.patch b/patches/glibc-2.5/generic/gentoo/1050_all_glibc-fix-printf-overflow-with-large-precisions.patch new file mode 100644 index 0000000..dc5f4db --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1050_all_glibc-fix-printf-overflow-with-large-precisions.patch @@ -0,0 +1,79 @@ +http://bugs.gentoo.org/176712 + +---------------------------- +revision 1.139 +date: 2007/05/07 03:43:55; author: drepper; state: Exp; lines: +3 -2 +(process_string_arg): Optimize ridiculous precision in wide char code +printing multi-byte string. +---------------------------- +revision 1.138 +date: 2007/05/05 04:41:35; author: drepper; state: Exp; lines: +2 -2 +(process_string_arg): Adjust call to __mbsnrtowcs after last change. +---------------------------- +revision 1.137 +date: 2007/05/02 08:15:50; author: drepper; state: Exp; lines: +2 -1 +(process_string_arg): Use a VLA rather than fixed length array for ignore. +---------------------------- +revision 1.136 +date: 2007/05/01 04:11:26; author: drepper; state: Exp; lines: +15 -9 +(process_string_arg): Don't overflow the stack for large precisions. +---------------------------- + +--- + stdio-common/vfprintf.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +Index: glibc-2.5/stdio-common/vfprintf.c +=================================================================== +--- glibc-2.5.orig/stdio-common/vfprintf.c ++++ glibc-2.5/stdio-common/vfprintf.c +@@ -1025,10 +1025,11 @@ vfprintf (FILE *s, const CHAR_T *format, + const char *mbs = (const char *) string; \ + mbstate_t mbstate; \ + \ +- len = prec != -1 ? (size_t) prec : strlen (mbs); \ ++ len = prec != -1 ? __strnlen (mbs, (size_t) prec) : strlen (mbs); \ + \ + /* Allocate dynamically an array which definitely is long \ +- enough for the wide character version. */ \ ++ enough for the wide character version. Each byte in the \ ++ multi-byte string can produce at most one wide character. */ \ + if (__libc_use_alloca (len * sizeof (wchar_t))) \ + string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ + else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \ +@@ -1159,19 +1160,26 @@ vfprintf (FILE *s, const CHAR_T *format, + else \ + { \ + /* In case we have a multibyte character set the \ +- situation is more compilcated. We must not copy \ ++ situation is more complicated. We must not copy \ + bytes at the end which form an incomplete character. */\ +- wchar_t ignore[prec]; \ ++ size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\ ++ wchar_t ignore[ignore_size]; \ + const char *str2 = string; \ +- mbstate_t ps; \ ++ const char *strend = string + prec; \ ++ if (strend < string) \ ++ strend = (const char *) UINTPTR_MAX; \ + \ ++ mbstate_t ps; \ + memset (&ps, '\0', sizeof (ps)); \ +- if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps) \ +- == (size_t) -1) \ +- { \ +- done = -1; \ +- goto all_done; \ +- } \ ++ \ ++ while (str2 != NULL && str2 < strend) \ ++ if (__mbsnrtowcs (ignore, &str2, strend - str2, \ ++ ignore_size, &ps) == (size_t) -1) \ ++ { \ ++ done = -1; \ ++ goto all_done; \ ++ } \ ++ \ + if (str2 == NULL) \ + len = strlen (string); \ + else \ diff --git a/patches/glibc-2.5/generic/gentoo/1055_all_glibc-resolv-dynamic.patch b/patches/glibc-2.5/generic/gentoo/1055_all_glibc-resolv-dynamic.patch new file mode 100644 index 0000000..901f90f --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1055_all_glibc-resolv-dynamic.patch @@ -0,0 +1,44 @@ +ripped from SuSE + +if /etc/resolv.conf is updated, then make sure applications +already running get the updated information. + +http://bugs.gentoo.org/177416 + +--- + resolv/res_libc.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +Index: glibc-2.5/resolv/res_libc.c +=================================================================== +--- glibc-2.5.orig/resolv/res_libc.c ++++ glibc-2.5/resolv/res_libc.c +@@ -22,6 +22,7 @@ + #include <arpa/nameser.h> + #include <resolv.h> + #include <bits/libc-lock.h> ++#include <sys/stat.h> + + + /* The following bit is copied from res_data.c (where it is #ifdef'ed +@@ -95,6 +96,20 @@ int + __res_maybe_init (res_state resp, int preinit) + { + if (resp->options & RES_INIT) { ++ static time_t last_mtime, last_check; ++ time_t now; ++ struct stat statbuf; ++ ++ time (&now); ++ if (now != last_check) { ++ last_check = now; ++ if (stat (_PATH_RESCONF, &statbuf) == 0 && last_mtime != statbuf.st_mtime) { ++ last_mtime = statbuf.st_mtime; ++ atomicinclock (lock); ++ atomicinc (__res_initstamp); ++ atomicincunlock (lock); ++ } ++ } + if (__res_initstamp != resp->_u._ext.initstamp) { + if (resp->nscount > 0) { + __res_iclose (resp, true); diff --git a/patches/glibc-2.5/generic/gentoo/1060_all_glibc-cvs-getcwd-path-max.patch b/patches/glibc-2.5/generic/gentoo/1060_all_glibc-cvs-getcwd-path-max.patch new file mode 100644 index 0000000..c31c51a --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1060_all_glibc-cvs-getcwd-path-max.patch @@ -0,0 +1,18 @@ +http://sourceware.org/ml/libc-alpha/2006-06/msg00068.html + +--- + sysdeps/unix/sysv/linux/getcwd.c | 1 + + 1 file changed, 1 insertion(+) + +Index: glibc-2.5/sysdeps/unix/sysv/linux/getcwd.c +=================================================================== +--- glibc-2.5.orig/sysdeps/unix/sysv/linux/getcwd.c ++++ glibc-2.5/sysdeps/unix/sysv/linux/getcwd.c +@@ -24,6 +24,7 @@ + #include <limits.h> + #include <stdlib.h> + #include <unistd.h> ++#include <sys/param.h> + + #include <sysdep.h> + #include <sys/syscall.h> diff --git a/patches/glibc-2.5/generic/gentoo/1075_all_glibc-section-comments.patch b/patches/glibc-2.5/generic/gentoo/1075_all_glibc-section-comments.patch new file mode 100644 index 0000000..bf2c09b --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1075_all_glibc-section-comments.patch @@ -0,0 +1,29 @@ +http://sources.redhat.com/ml/binutils/2004-04/msg00665.html + +fixes building on some architectures (like m68k/arm/cris/etc...) because +it does the right thing + +--- + include/libc-symbols.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: glibc-2.5/include/libc-symbols.h +=================================================================== +--- glibc-2.5.orig/include/libc-symbols.h ++++ glibc-2.5/include/libc-symbols.h +@@ -232,12 +232,12 @@ + # define __make_section_unallocated(section_string) + # endif + +-/* Tacking on "\n\t#" to the section name makes gcc put it's bogus ++/* Tacking on "\n#APP\n\t#" to the section name makes gcc put it's bogus + section attributes on what looks like a comment to the assembler. */ + # ifdef HAVE_SECTION_QUOTES +-# define __sec_comment "\"\n\t#\"" ++# define __sec_comment "\"\n#APP\n\t#\"" + # else +-# define __sec_comment "\n\t#" ++# define __sec_comment "\n#APP\n\t#" + # endif + # define link_warning(symbol, msg) \ + __make_section_unallocated (".gnu.warning." #symbol) \ diff --git a/patches/glibc-2.5/generic/gentoo/1090_all_glibc-2.3.6-fix-pr631.patch b/patches/glibc-2.5/generic/gentoo/1090_all_glibc-2.3.6-fix-pr631.patch new file mode 100644 index 0000000..2c26093 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1090_all_glibc-2.3.6-fix-pr631.patch @@ -0,0 +1,52 @@ +From dank@kegel.com +Wed Jun 15 09:12:43 PDT 2005 + +Fixes + +build-glibc/libc.a(nsswitch.o)(.data+0x64): undefined reference to `_nss_files_getaliasent_r' +build-glibc/libc.a(nsswitch.o)(.data+0x6c): undefined reference to `_nss_files_endaliasent' +... 53 lines deleted ... +build-glibc/libc.a(nsswitch.o)(.data+0x21c): undefined reference to `_nss_files_getspnam_r' +collect2: ld returned 1 exit status +make[2]: *** [/build/gcc-3.4.3-glibc-2.3.5-hdrs-2.6.11.2/i686-unknown-linux-gnu/build-glibc/elf/ldconfig] Error 1 + +when building glibc with --enable-static-nss. + +See http://sources.redhat.com/bugzilla/show_bug.cgi?id=631 + +--- + Makeconfig | 2 +- + elf/Makefile | 7 +++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +Index: glibc-2.5/Makeconfig +=================================================================== +--- glibc-2.5.orig/Makeconfig ++++ glibc-2.5/Makeconfig +@@ -510,7 +510,7 @@ endif + + # The static libraries. + ifeq (yes,$(build-static)) +-link-libc-static = $(common-objpfx)libc.a $(static-gnulib) $(common-objpfx)libc.a ++link-libc-static = $(common-objpfx)libc.a $(static-gnulib) $(otherlibs) $(common-objpfx)libc.a + else + ifeq (yes,$(build-shared)) + # We can try to link the programs with lib*_pic.a... +Index: glibc-2.5/elf/Makefile +=================================================================== +--- glibc-2.5.orig/elf/Makefile ++++ glibc-2.5/elf/Makefile +@@ -120,6 +120,13 @@ install-others = $(inst_slibdir)/$(rtld- + install-bin-script = ldd + endif + ++ifeq (yes,$(build-static-nss)) ++nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss) ++resolvobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)resolv) ++otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libnss_dns.a \ ++ $(resolvobjdir)/libresolv.a ++endif ++ + others = sprof sln + install-bin = sprof + others-static = sln diff --git a/patches/glibc-2.5/generic/gentoo/1100_all_glibc-2.3.3-china.patch b/patches/glibc-2.5/generic/gentoo/1100_all_glibc-2.3.3-china.patch new file mode 100644 index 0000000..2033b3f --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1100_all_glibc-2.3.3-china.patch @@ -0,0 +1,35 @@ +--- + localedata/locales/zh_TW | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: glibc-2.5/localedata/locales/zh_TW +=================================================================== +--- glibc-2.5.orig/localedata/locales/zh_TW ++++ glibc-2.5/localedata/locales/zh_TW +@@ -1,7 +1,7 @@ + comment_char % + escape_char / + % +-% Chinese language locale for Taiwan R.O.C. ++% Chinese language locale for Taiwan + % charmap: BIG5-CP950 + % + % Original Author: +@@ -17,7 +17,7 @@ escape_char / + % Reference: http://wwwold.dkuug.dk/JTC1/SC22/WG20/docs/n690.pdf + + LC_IDENTIFICATION +-title "Chinese locale for Taiwan R.O.C." ++title "Chinese locale for Taiwan" + source "" + address "" + contact "" +@@ -25,7 +25,7 @@ email "bug-glibc-locales@gnu.org" + tel "" + fax "" + language "Chinese" +-territory "Taiwan R.O.C." ++territory "Taiwan" + revision "0.2" + date "2000-08-02" + % diff --git a/patches/glibc-2.5/generic/gentoo/1120_all_glibc-2.5-strict-aliasing.patch b/patches/glibc-2.5/generic/gentoo/1120_all_glibc-2.5-strict-aliasing.patch new file mode 100644 index 0000000..42176c3 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1120_all_glibc-2.5-strict-aliasing.patch @@ -0,0 +1,92 @@ +workaround strict aliasing warnings on individual files rather than +forcing the whole build with -fno-strict-aliasing + +http://bugs.gentoo.org/155906 + +note that we leave the logout.c and logwtmp.c warnings alone as the +code path that invokes the warning should not be executed when the +warning is applicable. + +--- + libio/Makefile | 4 ++-- + nis/Makefile | 3 +++ + nptl/Makefile | 2 ++ + nss/Makefile | 2 ++ + sunrpc/Makefile | 2 +- + 5 files changed, 10 insertions(+), 3 deletions(-) + +Index: glibc-2.5/libio/Makefile +=================================================================== +--- glibc-2.5.orig/libio/Makefile ++++ glibc-2.5/libio/Makefile +@@ -90,7 +90,7 @@ CFLAGS-fseeko.c = $(exceptions) + CFLAGS-ftello64.c = $(exceptions) + CFLAGS-ftello.c = $(exceptions) + CFLAGS-fwide.c = $(exceptions) +-CFLAGS-genops.c = $(exceptions) ++CFLAGS-genops.c = $(exceptions) -fno-strict-aliasing + CFLAGS-getc.c = $(exceptions) + CFLAGS-getchar.c = $(exceptions) + CFLAGS-getwc.c = $(exceptions) +@@ -132,7 +132,7 @@ CFLAGS-putwc.c = $(exceptions) + CFLAGS-putwchar.c = $(exceptions) + CFLAGS-rewind.c = $(exceptions) + CFLAGS-wfileops.c = $(exceptions) +-CFLAGS-wgenops.c = $(exceptions) ++CFLAGS-wgenops.c = $(exceptions) -fno-strict-aliasing + CFLAGS-oldiofopen.c = $(exceptions) + CFLAGS-iofopen.c = $(exceptions) + CFLAGS-iofopen64.c = $(exceptions) +Index: glibc-2.5/nis/Makefile +=================================================================== +--- glibc-2.5.orig/nis/Makefile ++++ glibc-2.5/nis/Makefile +@@ -67,6 +67,9 @@ libnss_nisplus-routines := $(addprefix n + nss-nisplus + libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes)) + ++CFLAGS-nis_xdr.c += -fno-strict-aliasing ++CFLAGS-yp_xdr.c += -fno-strict-aliasing ++ + include ../Rules + + +Index: glibc-2.5/nptl/Makefile +=================================================================== +--- glibc-2.5.orig/nptl/Makefile ++++ glibc-2.5/nptl/Makefile +@@ -192,6 +192,8 @@ CFLAGS-tcdrain.c = -fexceptions -fasynch + + CFLAGS-pt-system.c = -fexceptions + ++CFLAGS-unwind-dw2.c += -fno-strict-aliasing ++ + # Don't generate deps for calls with no sources. See sysdeps/unix/Makefile. + omit-deps = $(unix-syscalls:%=ptw-%) + +Index: glibc-2.5/nss/Makefile +=================================================================== +--- glibc-2.5.orig/nss/Makefile ++++ glibc-2.5/nss/Makefile +@@ -71,6 +71,8 @@ ifneq ($(build-static-nss),yes) + libnss_files-inhibit-o = $(filter-out .os,$(object-suffixes)) + endif + ++CFLAGS-nsswitch.c += -fno-strict-aliasing ++ + include ../Rules + + +Index: glibc-2.5/sunrpc/Makefile +=================================================================== +--- glibc-2.5.orig/sunrpc/Makefile ++++ glibc-2.5/sunrpc/Makefile +@@ -127,7 +127,7 @@ CFLAGS-pmap_rmt.c = -fexceptions + CFLAGS-clnt_perr.c = -fexceptions + CFLAGS-openchild.c = -fexceptions + +-CPPFLAGS += -D_RPC_THREAD_SAFE_ ++CPPFLAGS += -D_RPC_THREAD_SAFE_ -fno-strict-aliasing + + include ../Rules + diff --git a/patches/glibc-2.5/generic/gentoo/1130_all_glibc-2.4-undefine-__i686.patch b/patches/glibc-2.5/generic/gentoo/1130_all_glibc-2.4-undefine-__i686.patch new file mode 100644 index 0000000..99964bb --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1130_all_glibc-2.4-undefine-__i686.patch @@ -0,0 +1,49 @@ +If gcc is configured to generate i686 code or better by default (like +when using the --with-arch=pentium3 configure option), then the __i686 +macro will always be defined automatically and thus screw up the +compilation of some .S files. +http://bugs.gentoo.org/131108 +http://sourceware.org/ml/libc-alpha/2006-04/msg00090.html + +2006-04-25 Mike Frysinger <vapier@gentoo.org> + + * sysdeps/i386/sysdep.h (__i686): Undefine. + +--- + nptl/sysdeps/pthread/pt-initfini.c | 3 +++ + sysdeps/i386/sysdep.h | 8 ++++++++ + 2 files changed, 11 insertions(+) + +Index: glibc-2.5/nptl/sysdeps/pthread/pt-initfini.c +=================================================================== +--- glibc-2.5.orig/nptl/sysdeps/pthread/pt-initfini.c ++++ glibc-2.5/nptl/sysdeps/pthread/pt-initfini.c +@@ -45,6 +45,9 @@ + /* Embed an #include to pull in the alignment and .end directives. */ + asm ("\n#include \"defs.h\""); + ++/* Embed an #include to pull in asm settings. */ ++asm ("\n#ifdef __i686__\n#include <sysdep.h>\n#endif"); ++ + /* The initial common code ends here. */ + asm ("\n/*@HEADER_ENDS*/"); + +Index: glibc-2.5/sysdeps/i386/sysdep.h +=================================================================== +--- glibc-2.5.orig/sysdeps/i386/sysdep.h ++++ glibc-2.5/sysdeps/i386/sysdep.h +@@ -17,6 +17,14 @@ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + ++/* ++ * When building for i686 targets or better, gcc automatically defines ++ * '__i686' to '1' for us which causes trouble when using section names ++ * like '__i686.get_pc_thunk.reg'. Since we check for __i686__ in the ++ * code, killing '__i686' shouldn't be a problem. ++ */ ++#undef __i686 ++ + #include <sysdeps/generic/sysdep.h> + + #ifdef __ASSEMBLER__ diff --git a/patches/glibc-2.5/generic/gentoo/1160_all_glibc-2.5-filter-files-for-headers-test.patch b/patches/glibc-2.5/generic/gentoo/1160_all_glibc-2.5-filter-files-for-headers-test.patch new file mode 100644 index 0000000..5dddd45 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1160_all_glibc-2.5-filter-files-for-headers-test.patch @@ -0,0 +1,28 @@ +Fix running test when built with USE=profile + +http://bugs.gentoo.org/177359 +http://sourceware.org/bugzilla/show_bug.cgi?id=3840 + +2007-01-12 Ulrich Drepper <drepper@redhat.com> + + [BZ #3840] + * scripts/check-local-headers.sh: Restrict to testing .o.d, .os.d, + and .oS.d files. + +--- + scripts/check-local-headers.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: glibc-2.5/scripts/check-local-headers.sh +=================================================================== +--- glibc-2.5.orig/scripts/check-local-headers.sh ++++ glibc-2.5/scripts/check-local-headers.sh +@@ -26,7 +26,7 @@ cd "$objpfx" + + # Search all dependency files for file names in the include directory. + # There are a few system headers we are known to use. +-if fgrep "$includedir" */*.d | ++if fgrep "$includedir" */*.{o,os,oS}.d | + fgrep -v "$includedir/asm" | + fgrep -v "$includedir/linux" | + fgrep -v "$includedir/selinux" | diff --git a/patches/glibc-2.5/generic/gentoo/1600_all_glibc-hwcap-mask-secure.patch b/patches/glibc-2.5/generic/gentoo/1600_all_glibc-hwcap-mask-secure.patch new file mode 100644 index 0000000..c5a2a17 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/1600_all_glibc-hwcap-mask-secure.patch @@ -0,0 +1,36 @@ +http://bugs.gentoo.org/183844 + +mark LD_HWCAP_MASK as unsecure so that integer overflow bugs cannot cause +problems for setid binaries + +--- + elf/rtld.c | 3 ++- + sysdeps/generic/unsecvars.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +Index: glibc-2.5/elf/rtld.c +=================================================================== +--- glibc-2.5.orig/elf/rtld.c ++++ glibc-2.5/elf/rtld.c +@@ -2580,7 +2580,8 @@ process_envvars (enum mode *modep) + + case 10: + /* Mask for the important hardware capabilities. */ +- if (memcmp (envline, "HWCAP_MASK", 10) == 0) ++ if (!INTUSE(__libc_enable_secure) ++ && memcmp (envline, "HWCAP_MASK", 10) == 0) + GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, + 0, 0); + break; +Index: glibc-2.5/sysdeps/generic/unsecvars.h +=================================================================== +--- glibc-2.5.orig/sysdeps/generic/unsecvars.h ++++ glibc-2.5/sysdeps/generic/unsecvars.h +@@ -9,6 +9,7 @@ + "LD_DEBUG\0" \ + "LD_DEBUG_OUTPUT\0" \ + "LD_DYNAMIC_WEAK\0" \ ++ "LD_HWCAP_MASK\0" \ + "LD_LIBRARY_PATH\0" \ + "LD_ORIGIN_PATH\0" \ + "LD_PRELOAD\0" \ diff --git a/patches/glibc-2.5/generic/gentoo/6220_all_glibc-2.4-arm-cirrus-ep93xx-maverick-crunch-fpu.patch b/patches/glibc-2.5/generic/gentoo/6220_all_glibc-2.4-arm-cirrus-ep93xx-maverick-crunch-fpu.patch new file mode 100644 index 0000000..1ac3834 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/6220_all_glibc-2.4-arm-cirrus-ep93xx-maverick-crunch-fpu.patch @@ -0,0 +1,352 @@ +http://yann.poupet.free.fr/ep93xx/ +Add support for the Maverick Crunch FPU on Cirrus EP93XX processor series + +--- ports/sysdeps/arm/bits/endian.h ++++ ports/sysdeps/arm/bits/endian.h +@@ -12,7 +12,7 @@ + /* FPA floating point units are always big-endian, irrespective of the + CPU endianness. VFP floating point units use the same endianness + as the rest of the system. */ +-#ifdef __VFP_FP__ ++#if defined __VFP_FP__ || defined __MAVERICK__ + #define __FLOAT_WORD_ORDER __BYTE_ORDER + #else + #define __FLOAT_WORD_ORDER __BIG_ENDIAN +--- ports/sysdeps/arm/fpu/bits/fenv.h ++++ ports/sysdeps/arm/fpu/bits/fenv.h +@@ -20,6 +20,45 @@ + # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." + #endif + ++#if defined(__MAVERICK__) ++ ++/* Define bits representing exceptions in the FPU status word. */ ++enum ++ { ++ FE_INVALID = 1, ++#define FE_INVALID FE_INVALID ++ FE_OVERFLOW = 4, ++#define FE_OVERFLOW FE_OVERFLOW ++ FE_UNDERFLOW = 8, ++#define FE_UNDERFLOW FE_UNDERFLOW ++ FE_INEXACT = 16, ++#define FE_INEXACT FE_INEXACT ++ }; ++ ++/* Amount to shift by to convert an exception to a mask bit. */ ++#define FE_EXCEPT_SHIFT 5 ++ ++/* All supported exceptions. */ ++#define FE_ALL_EXCEPT \ ++ (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) ++ ++/* IEEE rounding modes. */ ++enum ++ { ++ FE_TONEAREST = 0, ++#define FE_TONEAREST FE_TONEAREST ++ FE_TOWARDZERO = 0x400, ++#define FE_TOWARDZERO FE_TOWARDZERO ++ FE_DOWNWARD = 0x800, ++#define FE_DOWNWARD FE_DOWNWARD ++ FE_UPWARD = 0xc00, ++#define FE_UPWARD FE_UPWARD ++ }; ++ ++#define FE_ROUND_MASK (FE_UPWARD) ++ ++#else /* FPA */ ++ + /* Define bits representing exceptions in the FPU status word. */ + enum + { +@@ -44,6 +83,8 @@ + modes exist, but you have to encode them in the actual instruction. */ + #define FE_TONEAREST 0 + ++#endif ++ + /* Type representing exception flags. */ + typedef unsigned long int fexcept_t; + +--- ports/sysdeps/arm/fpu/bits/setjmp.h ++++ ports/sysdeps/arm/fpu/bits/setjmp.h +@@ -28,7 +28,11 @@ + #ifndef _ASM + /* Jump buffer contains v1-v6, sl, fp, sp and pc. Other registers are not + saved. */ ++#ifdef __MAVERICK__ ++typedef int __jmp_buf[34]; ++#else + typedef int __jmp_buf[22]; + #endif ++#endif + + #endif +--- ports/sysdeps/arm/fpu/jmpbuf-offsets.h ++++ ports/sysdeps/arm/fpu/jmpbuf-offsets.h +@@ -17,4 +17,8 @@ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + ++#ifdef __MAVERICK__ ++#define __JMP_BUF_SP 32 ++#else + #define __JMP_BUF_SP 20 ++#endif +--- ports/sysdeps/arm/fpu/fegetround.c ++++ ports/sysdeps/arm/fpu/fegetround.c +@@ -18,9 +18,21 @@ + 02111-1307 USA. */ + + #include <fenv.h> ++#include <fpu_control.h> + + int + fegetround (void) + { ++#if defined(__MAVERICK__) ++ ++ unsigned long temp; ++ ++ _FPU_GETCW (temp); ++ return temp & FE_ROUND_MASK; ++ ++#else /* FPA */ ++ + return FE_TONEAREST; /* Easy. :-) */ ++ ++#endif + } +--- ports/sysdeps/arm/fpu/fesetround.c ++++ ports/sysdeps/arm/fpu/fesetround.c +@@ -18,12 +18,28 @@ + 02111-1307 USA. */ + + #include <fenv.h> ++#include <fpu_control.h> + + int + fesetround (int round) + { ++#if defined(__MAVERICK__) ++ unsigned long temp; ++ ++ if (round & ~FE_ROUND_MASK) ++ return 1; ++ ++ _FPU_GETCW (temp); ++ temp = (temp & ~FE_ROUND_MASK) | round; ++ _FPU_SETCW (temp); ++ return 0; ++ ++#else /* FPA */ ++ + /* We only support FE_TONEAREST, so there is no need for any work. */ + return (round == FE_TONEAREST)?0:1; ++ ++#endif + } + + libm_hidden_def (fesetround) +--- ports/sysdeps/arm/fpu/fpu_control.h ++++ ports/sysdeps/arm/fpu/fpu_control.h +@@ -1,5 +1,6 @@ + /* FPU control word definitions. ARM version. +- Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. ++ Copyright (C) 1996, 1997, 1998, 2000, 2005 ++ 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 +@@ -20,6 +21,79 @@ + #ifndef _FPU_CONTROL_H + #define _FPU_CONTROL_H + ++#if defined(__MAVERICK__) ++ ++/* DSPSC register: (from EP9312 User's Guide) ++ * ++ * bits 31..29 - DAID ++ * bits 28..26 - HVID ++ * bits 25..24 - RSVD ++ * bit 23 - ISAT ++ * bit 22 - UI ++ * bit 21 - INT ++ * bit 20 - AEXC ++ * bits 19..18 - SAT ++ * bits 17..16 - FCC ++ * bit 15 - V ++ * bit 14 - FWDEN ++ * bit 13 - Invalid ++ * bit 12 - Denorm ++ * bits 11..10 - RM ++ * bits 9..5 - IXE, UFE, OFE, RSVD, IOE ++ * bits 4..0 - IX, UF, OF, RSVD, IO ++ */ ++ ++/* masking of interrupts */ ++#define _FPU_MASK_IM (1 << 5) /* invalid operation */ ++#define _FPU_MASK_ZM 0 /* divide by zero */ ++#define _FPU_MASK_OM (1 << 7) /* overflow */ ++#define _FPU_MASK_UM (1 << 8) /* underflow */ ++#define _FPU_MASK_PM (1 << 9) /* inexact */ ++#define _FPU_MASK_DM 0 /* denormalized operation */ ++ ++#define _FPU_RESERVED 0xfffff000 /* These bits are reserved. */ ++ ++#define _FPU_DEFAULT 0x00b00000 /* Default value. */ ++#define _FPU_IEEE 0x00b003a0 /* Default + exceptions enabled. */ ++ ++/* Type of the control word. */ ++typedef unsigned int fpu_control_t; ++ ++/* Macros for accessing the hardware control word. */ ++#define _FPU_GETCW(cw) ({ \ ++ register int __t1, __t2; \ ++ \ ++ __asm__ volatile ( \ ++ "cfmvr64l %1, mvdx0\n\t" \ ++ "cfmvr64h %2, mvdx0\n\t" \ ++ "cfmv32sc mvdx0, dspsc\n\t" \ ++ "cfmvr64l %0, mvdx0\n\t" \ ++ "cfmv64lr mvdx0, %1\n\t" \ ++ "cfmv64hr mvdx0, %2" \ ++ : "=r" (cw), "=r" (__t1), "=r" (__t2) \ ++ ); \ ++}) ++ ++#define _FPU_SETCW(cw) ({ \ ++ register int __t0, __t1, __t2; \ ++ \ ++ __asm__ volatile ( \ ++ "cfmvr64l %1, mvdx0\n\t" \ ++ "cfmvr64h %2, mvdx0\n\t" \ ++ "cfmv64lr mvdx0, %0\n\t" \ ++ "cfmvsc32 dspsc, mvdx0\n\t" \ ++ "cfmv64lr mvdx0, %1\n\t" \ ++ "cfmv64hr mvdx0, %2" \ ++ : "=r" (__t0), "=r" (__t1), "=r" (__t2) \ ++ : "0" (cw) \ ++ ); \ ++}) ++ ++/* Default control word set at startup. */ ++extern fpu_control_t __fpu_control; ++ ++#else /* FPA */ ++ + /* We have a slight terminology confusion here. On the ARM, the register + * we're interested in is actually the FPU status word - the FPU control + * word is something different (which is implementation-defined and only +@@ -99,4 +173,6 @@ + /* Default control word set at startup. */ + extern fpu_control_t __fpu_control; + ++#endif ++ + #endif /* _FPU_CONTROL_H */ +--- ports/sysdeps/arm/fpu/__longjmp.S ++++ ports/sysdeps/arm/fpu/__longjmp.S +@@ -30,7 +30,33 @@ + movs r0, r1 /* get the return value in place */ + moveq r0, #1 /* can't let setjmp() return zero! */ + ++#ifdef __MAVERICK__ ++ cfldrd mvd4, [ip], #8 ++ nop ++ cfldrd mvd5, [ip], #8 ++ nop ++ cfldrd mvd6, [ip], #8 ++ nop ++ cfldrd mvd7, [ip], #8 ++ nop ++ cfldrd mvd8, [ip], #8 ++ nop ++ cfldrd mvd9, [ip], #8 ++ nop ++ cfldrd mvd10, [ip], #8 ++ nop ++ cfldrd mvd11, [ip], #8 ++ nop ++ cfldrd mvd12, [ip], #8 ++ nop ++ cfldrd mvd13, [ip], #8 ++ nop ++ cfldrd mvd14, [ip], #8 ++ nop ++ cfldrd mvd15, [ip], #8 ++#else + lfmfd f4, 4, [ip] ! /* load the floating point regs */ ++#endif + + LOADREGS(ia, ip, {v1-v6, sl, fp, sp, pc}) + END (__longjmp) +--- ports/sysdeps/arm/fpu/setjmp.S ++++ ports/sysdeps/arm/fpu/setjmp.S +@@ -24,11 +24,41 @@ + + ENTRY (__sigsetjmp) + /* Save registers */ ++#ifdef __MAVERICK__ ++ cfstrd mvd4, [r0], #8 ++ nop ++ cfstrd mvd5, [r0], #8 ++ nop ++ cfstrd mvd6, [r0], #8 ++ nop ++ cfstrd mvd7, [r0], #8 ++ nop ++ cfstrd mvd8, [r0], #8 ++ nop ++ cfstrd mvd9, [r0], #8 ++ nop ++ cfstrd mvd10, [r0], #8 ++ nop ++ cfstrd mvd11, [r0], #8 ++ nop ++ cfstrd mvd12, [r0], #8 ++ nop ++ cfstrd mvd13, [r0], #8 ++ nop ++ cfstrd mvd14, [r0], #8 ++ nop ++ cfstrd mvd15, [r0], #8 ++#else + sfmea f4, 4, [r0]! ++#endif + stmia r0, {v1-v6, sl, fp, sp, lr} + + /* Restore pointer to jmp_buf */ ++#ifdef __MAVERICK__ ++ sub r0, r0, #96 ++#else + sub r0, r0, #48 ++#endif + + /* Make a tail call to __sigjmp_save; it takes the same args. */ + B PLTJMP(C_SYMBOL_NAME(__sigjmp_save)) +--- ports/sysdeps/arm/gccframe.h ++++ ports/sysdeps/arm/gccframe.h +@@ -17,6 +17,10 @@ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + ++#ifdef __MAVERICK__ ++#define FIRST_PSEUDO_REGISTER 43 ++#else + #define FIRST_PSEUDO_REGISTER 27 ++#endif + + #include <sysdeps/generic/gccframe.h> +--- ports/sysdeps/arm/gmp-mparam.h ++++ ports/sysdeps/arm/gmp-mparam.h +@@ -29,7 +29,7 @@ + #if defined(__ARMEB__) + # define IEEE_DOUBLE_MIXED_ENDIAN 0 + # define IEEE_DOUBLE_BIG_ENDIAN 1 +-#elif defined(__VFP_FP__) ++#elif defined(__VFP_FP__) || defined(__MAVERICK__) + # define IEEE_DOUBLE_MIXED_ENDIAN 0 + # define IEEE_DOUBLE_BIG_ENDIAN 0 + #else diff --git a/patches/glibc-2.5/generic/gentoo/6901_all_2.4-amd64-strings-20060609.patch b/patches/glibc-2.5/generic/gentoo/6901_all_2.4-amd64-strings-20060609.patch new file mode 100644 index 0000000..0bf7cbc --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/6901_all_2.4-amd64-strings-20060609.patch @@ -0,0 +1,2913 @@ +Patch for improved string handling on amd64 +http://sourceware.org/ml/libc-alpha/2006-05/msg00029.html + +Also, misc PIC/SHARED handling has been fixed up: +http://bugs.gentoo.org/124682 + +--- glibc-head/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c ++++ glibc-amd/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c +@@ -1,5 +1,5 @@ + #ifdef IS_IN_ldconfig + # include <sysdeps/i386/dl-procinfo.c> + #else +-# include <sysdeps/generic/dl-procinfo.c> ++# include <sysdeps/x86_64/dl-procinfo.c> + #endif +--- glibc-head/libc/sysdeps/x86_64/bzero.S ++++ glibc-amd/libc/sysdeps/x86_64/bzero.S +@@ -1,3 +1,5 @@ ++#define USE_AS_BZERO + #define memset __bzero + #include <sysdeps/x86_64/memset.S> ++ + weak_alias (__bzero, bzero) +--- glibc-head/libc/sysdeps/x86_64/dl-machine.h ++++ glibc-amd/libc/sysdeps/x86_64/dl-machine.h +@@ -1,4 +1,5 @@ +-/* Machine-dependent ELF dynamic relocation inline functions. x86-64 version. ++/* Machine-dependent ELF dynamic relocation inline functions (x86-64 version). ++ + Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>. +@@ -219,6 +220,53 @@ dl_platform_init (void) + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') + /* Avoid an empty string which would disturb us. */ + GLRO(dl_platform) = NULL; ++ ++ asm volatile ++ ( ++ "mov $0x80000000, %%eax # get highest level of support \n\t" ++ "cpuid \n\t" ++ "cmp $0x80000006, %%eax # check for L2 info support \n\t" ++ "jb 1f \n\t" ++ "xor %%eax, %%eax # get manufacturer string \n\t" ++ "cpuid \n\t" ++ "cmp $0x68747541, %%ebx # check for 'Auth'... \n\t" ++ "jne 4f \n\t" ++ "cmp $0x69746e65, %%edx # 'enti'... \n\t" ++ "jne 4f \n\t" ++ "cmp $0x444d4163, %%ecx # 'cAMD' \n\t" ++ "je 2f \n\t" ++ "4: \n\t" ++ "cmp $0x756e6547, %%ebx # check for 'Genu'... \n\t" ++ "jne 1f \n\t" ++ "cmp $0x49656e69, %%edx # 'ineI'... \n\t" ++ "jne 1f \n\t" ++ "cmp $0x6c65746e, %%ecx # 'ntel' \n\t" ++ "je 3f \n\t" ++ "jmp 1f \n\t" ++ "2: # AMD \n\t" ++ "mov $0x80000001, %%eax # get features support\n\t" ++ "cpuid \n\t" ++ "test $1 << 31, %%edx # check for 3DNow! support\n\t" ++ "setnzb %2 \n\t" ++ "mov $0x80000005, %%eax # get L1 info for AMD\n\t" ++ "cpuid \n\t" ++ "shr $24, %%ecx \n\t" ++ "shl $10, %%ecx # convert from KB to B \n\t" ++ "mov %%rcx, %0 \n\t" ++ "3: # AMD, Intel \n\t" ++ "mov $0x80000006, %%eax # get L2 info\n\t" ++ "cpuid \n\t" ++ "shr $16, %%ecx \n\t" ++ "shl $10, %%ecx # convert from KB to B \n\t" ++ "mov %%rcx, %1 \n\t" ++ "1: # other manufacturers\n\t" ++ : "=m" (GLRO (dl_cache1size)), "=m" (GLRO (dl_cache2size)), "=m" (GLRO (dl_prefetchw)) ++ : ++ : "%rax", "%rbx", "%rcx", "%rdx", "cc" ++ ); ++ ++ GLRO (dl_cache1sizehalf) = GLRO (dl_cache1size) / 2; ++ GLRO (dl_cache2sizehalf) = GLRO (dl_cache2size) / 2; + } + + static inline Elf64_Addr +--- glibc-head/libc/sysdeps/x86_64/dl-procinfo.c ++++ glibc-amd/libc/sysdeps/x86_64/dl-procinfo.c +@@ -0,0 +1,123 @@ ++/* Data for x86-64 version of processor capability information. ++ Copyright (C) 2004 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Andreas Jaeger <aj@suse.de>, 2004. ++ ++ 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. */ ++ ++/* This information must be kept in sync with the _DL_HWCAP_COUNT and ++ _DL_PLATFORM_COUNT definitions in procinfo.h. ++ ++ If anything should be added here check whether the size of each string ++ is still ok with the given array size. ++ ++ All the #ifdefs in the definitions ar equite irritating but ++ necessary if we want to avoid duplicating the information. There ++ are three different modes: ++ ++ - PROCINFO_DECL is defined. This means we are only interested in ++ declarations. ++ ++ - PROCINFO_DECL is not defined: ++ ++ + if SHARED is defined the file is included in an array ++ initializer. The .element = { ... } syntax is needed. ++ ++ + if SHARED is not defined a normal array initialization is ++ needed. ++ */ ++ ++#ifndef PROCINFO_CLASS ++#define PROCINFO_CLASS ++#endif ++ ++ /* _dl_cache1size: size of L1 cache */ ++#if !defined PROCINFO_DECL && defined SHARED ++ ._dl_cache1size ++#else ++PROCINFO_CLASS long int _dl_cache1size ++#endif ++#ifndef PROCINFO_DECL ++= 1024 * 32 /* defaults to 32 */ ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++, ++#endif ++ ++ /* _dl_cache1sizehalf: 1/2 size of L1 cache */ ++#if !defined PROCINFO_DECL && defined SHARED ++ ._dl_cache1sizehalf ++#else ++PROCINFO_CLASS long int _dl_cache1sizehalf ++#endif ++#ifndef PROCINFO_DECL ++= 1024 * 32 / 2 /* defaults to 16k */ ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++, ++#endif ++ ++ /* _dl_cache2size: size of L2 cache */ ++#if !defined PROCINFO_DECL && defined SHARED ++ ._dl_cache2size ++#else ++PROCINFO_CLASS long int _dl_cache2size ++#endif ++#ifndef PROCINFO_DECL ++= 1024 * 1024 /* defaults to 1M */ ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++, ++#endif ++ ++ /* _dl_cache2sizehalf: 1/2 size of L2 cache */ ++#if !defined PROCINFO_DECL && defined SHARED ++ ._dl_cache2sizehalf ++#else ++PROCINFO_CLASS long int _dl_cache2sizehalf ++#endif ++#ifndef PROCINFO_DECL ++= 1024 * 1024 / 2 /* defaults to 512k */ ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++, ++#endif ++ ++ /* _dl_prefetchw: prefetchw supported */ ++#if !defined PROCINFO_DECL && defined SHARED ++ ._dl_prefetchw ++#else ++PROCINFO_CLASS int _dl_prefetchw ++#endif ++#ifndef PROCINFO_DECL ++= 0 /* defaults to no */ ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++, ++#endif ++ ++#undef PROCINFO_DECL ++#undef PROCINFO_CLASS +--- glibc-head/libc/sysdeps/x86_64/elf/rtld-global-offsets.sym ++++ glibc-amd/libc/sysdeps/x86_64/elf/rtld-global-offsets.sym +@@ -0,0 +1,11 @@ ++#define SHARED 1 ++ ++#include <ldsodefs.h> ++ ++#define rtdl_global_offsetof(mem) offsetof (struct rtld_global_ro, mem) ++ ++RTLD_GLOBAL_DL_CACHE1SIZE rtdl_global_offsetof (_dl_cache1size) ++RTLD_GLOBAL_DL_CACHE1SIZEHALF rtdl_global_offsetof (_dl_cache1sizehalf) ++RTLD_GLOBAL_DL_CACHE2SIZE rtdl_global_offsetof (_dl_cache2size) ++RTLD_GLOBAL_DL_CACHE2SIZEHALF rtdl_global_offsetof (_dl_cache2sizehalf) ++RTLD_GLOBAL_DL_PREFETCHW rtdl_global_offsetof (_dl_prefetchw) +--- glibc-head/libc/sysdeps/x86_64/Makefile ++++ glibc-amd/libc/sysdeps/x86_64/Makefile +@@ -4,6 +4,9 @@ long-double-fcts = yes + ifeq ($(subdir),csu) + sysdep_routines += hp-timing + elide-routines.os += hp-timing ++ ++# get offset to rtld_global._dl_* ++gen-as-const-headers += rtld-global-offsets.sym + endif + + ifeq ($(subdir),gmon) +--- glibc-head/libc/sysdeps/x86_64/memcmp.S ++++ glibc-amd/libc/sysdeps/x86_64/memcmp.S +@@ -0,0 +1,328 @@ ++# (c) 2002 Advanced Micro Devices, Inc. ++# YOUR USE OF THIS CODE IS SUBJECT TO THE TERMS ++# AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++# LICENSE FOUND IN THE "README" FILE THAT IS ++# INCLUDED WITH THIS FILE ++ ++#include "sysdep.h" ++#if defined PIC && defined SHARED ++# include <rtld-global-offsets.h> ++#endif ++ ++#if defined PIC && defined SHARED ++ .globl _rtld_local_ro ++ .hidden _rtld_local_ro ++ .set _rtld_local_ro,_rtld_global_ro ++#endif ++ ++ .text ++ ++ENTRY (memcmp) # (const void *, const void*, size_t) ++ ++L(try1): # up to 8B ++ cmp $8, %rdx ++ jae L(1after) ++ ++L(1): # 1-byte ++ test %rdx, %rdx ++ mov $0, %eax ++ jz L(exit) ++ ++L(1loop): ++ movzbl (%rdi), %eax ++ movzbl (%rsi), %ecx ++ sub %ecx, %eax ++ jnz L(exit) ++ ++ dec %rdx ++ ++ lea 1 (%rdi), %rdi ++ lea 1 (%rsi), %rsi ++ ++ jnz L(1loop) ++ ++L(exit): ++ rep ++ ret ++ ++ .p2align 4 ++ ++L(1after): ++ ++L(8try): # up to 32B ++ cmp $32, %rdx ++ jae L(8after) ++ ++L(8): # 8-byte ++ mov %edx, %ecx ++ shr $3, %ecx ++ jz L(1) ++ ++ .p2align 4 ++ ++L(8loop): ++ mov (%rsi), %rax ++ cmp (%rdi), %rax ++ jne L(1) ++ ++ sub $8, %rdx ++ dec %ecx ++ ++ lea 8 (%rsi), %rsi ++ lea 8 (%rdi), %rdi ++ ++ jnz L(8loop) ++ ++L(8skip): ++ and $7, %edx ++ jnz L(1) ++ ++ xor %eax, %eax ++ ret ++ ++ .p2align 4 ++ ++L(8after): ++ ++L(32try): # up to 2KB ++ cmp $2048, %rdx ++ ja L(32after) ++ ++L(32): # 32-byte ++ mov %edx, %ecx ++ shr $5, %ecx ++ jz L(8) ++ ++ .p2align 4 ++ ++L(32loop): ++ mov (%rsi), %rax ++ mov 8 (%rsi), %r8 ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ sub (%rdi), %rax ++ sub 8 (%rdi), %r8 ++ sub 16 (%rdi), %r9 ++ sub 24 (%rdi), %r10 ++ ++ or %rax, %r8 ++ or %r9, %r10 ++ or %r8, %r10 ++ jnz L(8) ++ ++ sub $32, %rdx ++ dec %ecx ++ ++ lea 32 (%rsi), %rsi ++ lea 32 (%rdi), %rdi ++ ++ jnz L(32loop) ++ ++L(32skip): ++ and $31, %edx ++ jnz L(8) ++ ++ xor %eax, %eax ++ ret ++ ++ .p2align 4 ++ ++L(32after): ++ ++L(srctry): ++ mov %esi, %r8d # align by source ++ ++ and $7, %r8d ++ jz L(srcafter) # not unaligned ++ ++L(src): # align ++ lea -8 (%r8, %rdx), %rdx ++ sub $8, %r8d ++ ++# .p2align 4 ++ ++L(srcloop): ++ movzbl (%rdi), %eax ++ movzbl (%rsi), %ecx ++ sub %ecx, %eax ++ jnz L(exit) ++ ++ inc %r8d ++ ++ lea 1 (%rdi), %rdi ++ lea 1 (%rsi), %rsi ++ ++ jnz L(srcloop) ++ ++ .p2align 4 ++ ++L(srcafter): ++ ++L(64try): # up to 1/2 L1 ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %rcx ++ mov RTLD_GLOBAL_DL_CACHE1SIZEHALF (%rcx), %rcx ++# else ++ mov _dl_cache1sizehalf@GOTPCREL (%rip), %rcx ++ mov (%rcx), %rcx ++# endif ++#else ++ mov _dl_cache1sizehalf, %rcx ++#endif ++ cmp %rdx, %rcx ++ cmova %rdx, %rcx ++ ++L(64): # 64-byte ++ shr $6, %rcx ++ jz L(32) ++ ++ .p2align 4 ++ ++L(64loop): ++ mov (%rsi), %rax ++ mov 8 (%rsi), %r8 ++ sub (%rdi), %rax ++ sub 8 (%rdi), %r8 ++ or %r8, %rax ++ ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ sub 16 (%rdi), %r9 ++ sub 24 (%rdi), %r10 ++ or %r10, %r9 ++ ++ or %r9, %rax ++ jnz L(32) ++ ++ mov 32 (%rsi), %rax ++ mov 40 (%rsi), %r8 ++ sub 32 (%rdi), %rax ++ sub 40 (%rdi), %r8 ++ or %r8, %rax ++ ++ mov 48 (%rsi), %r9 ++ mov 56 (%rsi), %r10 ++ sub 48 (%rdi), %r9 ++ sub 56 (%rdi), %r10 ++ or %r10, %r9 ++ ++ or %r9, %rax ++ jnz L(32) ++ ++ lea 64 (%rsi), %rsi ++ lea 64 (%rdi), %rdi ++ ++ sub $64, %rdx ++ dec %rcx ++ jnz L(64loop) ++ ++# .p2align 4 ++ ++L(64skip): ++ cmp $2048, %rdx ++ ja L(64after) ++ ++ test %edx, %edx ++ jnz L(32) ++ ++ xor %eax, %eax ++ ret ++ ++ .p2align 4 ++ ++L(64after): ++ ++L(128try): ++ ++L(128): # 128-byte ++ mov %rdx, %rcx ++ shr $7, %rcx ++ jz L(128skip) ++ ++ .p2align 4 ++ ++L(128loop): ++ prefetcht0 512 (%rsi) ++ prefetcht0 512 (%rdi) ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %r8 ++ sub (%rdi), %rax ++ sub 8 (%rdi), %r8 ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ sub 16 (%rdi), %r9 ++ sub 24 (%rdi), %r10 ++ ++ or %r8, %rax ++ or %r9, %r10 ++ or %r10, %rax ++ ++ mov 32 (%rsi), %r8 ++ mov 40 (%rsi), %r9 ++ sub 32 (%rdi), %r8 ++ sub 40 (%rdi), %r9 ++ mov 48 (%rsi), %r10 ++ mov 56 (%rsi), %r11 ++ sub 48 (%rdi), %r10 ++ sub 56 (%rdi), %r11 ++ ++ or %r9, %r8 ++ or %r11, %r10 ++ or %r10, %r8 ++ ++ or %r8, %rax ++ jnz L(32) ++ ++ prefetcht0 576 (%rsi) ++ prefetcht0 576 (%rdi) ++ ++ mov 64 (%rsi), %rax ++ mov 72 (%rsi), %r8 ++ sub 64 (%rdi), %rax ++ sub 72 (%rdi), %r8 ++ mov 80 (%rsi), %r9 ++ mov 88 (%rsi), %r10 ++ sub 80 (%rdi), %r9 ++ sub 88 (%rdi), %r10 ++ ++ or %r8, %rax ++ or %r9, %r10 ++ or %r10, %rax ++ ++ mov 96 (%rsi), %r8 ++ mov 104 (%rsi), %r9 ++ sub 96 (%rdi), %r8 ++ sub 104 (%rdi), %r9 ++ mov 112 (%rsi), %r10 ++ mov 120 (%rsi), %r11 ++ sub 112 (%rdi), %r10 ++ sub 120 (%rdi), %r11 ++ ++ or %r9, %r8 ++ or %r11, %r10 ++ or %r10, %r8 ++ ++ or %r8, %rax ++ jnz L(32) ++ ++ sub $128, %rdx ++ dec %rcx ++ ++ lea 128 (%rsi), %rsi ++ lea 128 (%rdi), %rdi ++ ++ jnz L(128loop) ++ ++L(128skip): ++ and $127, %edx ++ jnz L(32) ++ ++ xor %eax, %eax ++ ret ++ ++END (memcmp) ++ ++#undef bcmp ++weak_alias (memcmp, bcmp) +--- glibc-head/libc/sysdeps/x86_64/memcpy.S ++++ glibc-amd/libc/sysdeps/x86_64/memcpy.S +@@ -1,32 +1,22 @@ +-/* Highly optimized version for x86-64. +- Copyright (C) 1997, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Based on i586 version 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, write to the Free +- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +- 02111-1307 USA. */ ++# (c) 2002 Advanced Micro Devices, Inc. ++# YOUR USE OF THIS CODE IS SUBJECT TO THE TERMS ++# AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++# LICENSE FOUND IN THE "README" FILE THAT IS ++# INCLUDED WITH THIS FILE + + #include <sysdep.h> + #include "asm-syntax.h" + #include "bp-sym.h" + #include "bp-asm.h" ++#if defined PIC && defined SHARED ++# include <rtld-global-offsets.h> ++#endif + +-/* BEWARE: `#ifdef memcpy' means that memcpy is redefined as `mempcpy', +- and the return value is the byte after the last one copied in +- the destination. */ +-#define MEMPCPY_P (defined memcpy) ++#if defined PIC && defined SHARED ++ .globl _rtld_local_ro ++ .hidden _rtld_local_ro ++ .set _rtld_local_ro,_rtld_global_ro ++#endif + + .text + #if defined PIC && !defined NOT_IN_libc +@@ -35,67 +25,480 @@ ENTRY (__memcpy_chk) + jb HIDDEN_JUMPTARGET (__chk_fail) + END (__memcpy_chk) + #endif +-ENTRY (BP_SYM (memcpy)) +- /* Cutoff for the big loop is a size of 32 bytes since otherwise +- the loop will never be entered. */ +- cmpq $32, %rdx +- movq %rdx, %rcx +-#if !MEMPCPY_P +- movq %rdi, %r10 /* Save value. */ ++ ++ENTRY (memcpy) # (void *, const void*, size_t) ++ ++L(1try): # up to 16B ++ cmp $16, %rdx ++#if defined (USE_AS_MEMPCPY) ++ lea (%rdi, %rdx), %rax ++#else ++ mov %rdi, %rax + #endif ++ jae L(1after) ++ ++L(1): # 1-byte once ++ test $1, %dl ++ jz L(1a) ++ ++ movzbl (%rsi), %ecx ++ mov %cl, (%rdi) ++ ++ inc %rsi ++ inc %rdi ++ ++L(1a): # 2-byte once ++ test $2, %dl ++ jz L(1b) ++ ++ movzwl (%rsi), %ecx ++ mov %cx, (%rdi) ++ ++ add $2, %rsi ++ add $2, %rdi ++ ++L(1b): # 4-byte once ++ test $4, %dl ++ jz L(1c) ++ ++ mov (%rsi), %ecx ++ mov %ecx, (%rdi) ++ ++ add $4, %rsi ++ add $4, %rdi ++ ++L(1c): # 8-byte once ++ test $8, %dl ++ jz L(exit) ++ ++ mov (%rsi), %rcx ++ mov %rcx, (%rdi) ++ ++L(exit): ++ rep ++ ret ++ ++ .p2align 4 ++ ++L(1after): ++ push %rax ++ ++L(8try): # up to 32B ++ cmp $32, %rdx ++ jae L(8after) ++ ++L(8): # 8-byte loop ++ mov %edx, %ecx ++ shr $3, %ecx ++ jz L(8skip) ++ ++ .p2align 4 ++ ++L(8loop): ++ dec %ecx ++ ++ mov (%rsi), %rax ++ mov %rax, (%rdi) ++ ++ lea 8 (%rsi), %rsi ++ lea 8 (%rdi), %rdi ++ ++ jnz L(8loop) ++ ++L(8skip): ++ and $7, %edx # check for left overs ++ pop %rax ++ jnz L(1) ++ ++ rep ++ ret ++ ++ .p2align 4 ++ ++L(8after): ++ ++L(aligntry): ++ mov %edi, %r8d # align by destination ++ ++ and $7, %r8d ++ jz L(alignafter) # not unaligned ++ ++L(align): # align ++ lea -8 (%r8, %rdx), %rdx ++ sub $8, %r8d ++ ++ .p2align 4 ++ ++L(alignloop): ++ inc %r8d ++ ++ mov (%rsi), %al ++ mov %al, (%rdi) ++ ++ lea 1 (%rsi), %rsi ++ lea 1 (%rdi), %rdi ++ ++ jnz L(alignloop) ++ ++ .p2align 4 ++ ++L(alignafter): ++ ++L(32try): # up to 1KB ++ cmp $1024, %rdx ++ ja L(32after) ++ ++L(32): # 32-byte loop ++ mov %edx, %ecx ++ shr $5, %ecx ++ jz L(32skip) ++ ++ .p2align 4 ++ ++L(32loop): ++ dec %ecx ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %r8 ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ ++ mov %rax, (%rdi) ++ mov %r8, 8 (%rdi) ++ mov %r9, 16 (%rdi) ++ mov %r10, 24 (%rdi) ++ ++ lea 32 (%rsi), %rsi ++ lea 32 (%rdi), %rdi ++ ++ jz L(32skip) + +- /* We need this in any case. */ +- cld ++ dec %ecx + +- jbe 1f ++ mov (%rsi), %rax ++ mov 8 (%rsi), %r8 ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 + +- /* Align destination. */ +- movq %rdi, %rax +- negq %rax +- andq $7, %rax +- subq %rax, %rcx +- xchgq %rax, %rcx ++ mov %rax, (%rdi) ++ mov %r8, 8 (%rdi) ++ mov %r9, 16 (%rdi) ++ mov %r10, 24 (%rdi) + +- rep; movsb ++ lea 32 (%rsi), %rsi ++ lea 32 (%rdi), %rdi + +- movq %rax, %rcx +- subq $32, %rcx +- js 2f ++ jnz L(32loop) + + .p2align 4 +-3: + +- /* Now correct the loop counter. Please note that in the following +- code the flags are not changed anymore. */ +- subq $32, %rcx ++L(32skip): ++ and $31, %edx # check for left overs ++ jnz L(8) ++ ++ pop %rax ++ ret ++ ++ .p2align 4 ++ ++L(32after): ++ ++L(fasttry): # first 1/2 L1 ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %r11 ++ mov RTLD_GLOBAL_DL_CACHE1SIZEHALF (%r11), %r11 ++# else ++ mov _dl_cache1sizehalf@GOTPCREL (%rip), %r11 ++ mov (%r11), %r11 ++# endif ++#else ++ mov _dl_cache1sizehalf, %r11 ++#endif ++ cmp %rdx, %r11 ++ cmova %rdx, %r11 + +- movq (%rsi), %rax +- movq 8(%rsi), %rdx +- movq 16(%rsi), %r8 +- movq 24(%rsi), %r9 +- movq %rax, (%rdi) +- movq %rdx, 8(%rdi) +- movq %r8, 16(%rdi) +- movq %r9, 24(%rdi) ++L(fast): # good ol' MOVS ++ mov %r11, %rcx ++ and $-8, %r11 ++ shr $3, %rcx ++ jz L(fastskip) ++ ++ rep ++ movsq ++ ++L(fastskip): ++ sub %r11, %rdx # check for more ++ test $-8, %rdx ++ jnz L(fastafter) ++ ++ and $7, %edx # check for left overs ++ pop %rax ++ jnz L(1) + +- leaq 32(%rsi), %rsi +- leaq 32(%rdi), %rdi ++ rep ++ ret + +- jns 3b ++ .p2align 4 + +- /* Correct extra loop counter modification. */ +-2: addq $32, %rcx +-1: rep; movsb ++L(fastafter): + +-#if MEMPCPY_P +- movq %rdi, %rax /* Set return value. */ ++L(pretry): # first 1/2 L2 ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %r8 ++ mov RTLD_GLOBAL_DL_CACHE2SIZEHALF (%r8), %r8 + #else +- movq %r10, %rax /* Set return value. */ ++ mov _dl_cache2sizehalf@GOTPCREL (%rip), %r8 ++ mov (%r8), %r8 ++# endif ++#else ++ mov _dl_cache2sizehalf, %r8 ++#endif ++ cmp %rdx, %r8 ++ cmova %rdx, %r8 + ++L(pre): # 64-byte with prefetching ++ mov %r8, %rcx ++ and $-64, %r8 ++ shr $6, %rcx ++ jz L(preskip) ++ ++ push %r14 ++ push %r13 ++ push %r12 ++ push %rbx ++ ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %rax ++ cmpl $0, RTLD_GLOBAL_DL_PREFETCHW (%rax) ++# else ++ mov _dl_prefetchw@GOTPCREL (%rip), %rax ++ cmpl $0, (%rax) ++# endif ++#else ++ cmpl $0, _dl_prefetchw + #endif ++ jz L(preloop) ++ ++ .p2align 4 ++ ++L(prewloop): # to state M ++ dec %rcx ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %rbx ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ mov 32 (%rsi), %r11 ++ mov 40 (%rsi), %r12 ++ mov 48 (%rsi), %r13 ++ mov 56 (%rsi), %r14 ++ ++ prefetcht0 0 + 896 (%rsi) ++ prefetcht0 64 + 896 (%rsi) ++ ++ mov %rax, (%rdi) ++ mov %rbx, 8 (%rdi) ++ mov %r9, 16 (%rdi) ++ mov %r10, 24 (%rdi) ++ mov %r11, 32 (%rdi) ++ mov %r12, 40 (%rdi) ++ mov %r13, 48 (%rdi) ++ mov %r14, 56 (%rdi) ++ ++ lea 64 (%rsi), %rsi ++ lea 64 (%rdi), %rdi ++ ++ jz L(prebail) ++ ++ dec %rcx ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %rbx ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ mov 32 (%rsi), %r11 ++ mov 40 (%rsi), %r12 ++ mov 48 (%rsi), %r13 ++ mov 56 (%rsi), %r14 ++ ++ mov %rax, (%rdi) ++ mov %rbx, 8 (%rdi) ++ mov %r9, 16 (%rdi) ++ mov %r10, 24 (%rdi) ++ mov %r11, 32 (%rdi) ++ mov %r12, 40 (%rdi) ++ mov %r13, 48 (%rdi) ++ mov %r14, 56 (%rdi) ++ ++ prefetchw 896 - 64 (%rdi) ++ prefetchw 896 - 0 (%rdi) ++ ++ lea 64 (%rsi), %rsi ++ lea 64 (%rdi), %rdi ++ ++ jnz L(prewloop) ++ jmp L(prebail) ++ ++ .p2align 4 ++ ++L(preloop): # to state E ++ dec %rcx ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %rbx ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ mov 32 (%rsi), %r11 ++ mov 40 (%rsi), %r12 ++ mov 48 (%rsi), %r13 ++ mov 56 (%rsi), %r14 ++ ++ prefetcht0 896 + 0 (%rsi) ++ prefetcht0 896 + 64 (%rsi) ++ ++ mov %rax, (%rdi) ++ mov %rbx, 8 (%rdi) ++ mov %r9, 16 (%rdi) ++ mov %r10, 24 (%rdi) ++ mov %r11, 32 (%rdi) ++ mov %r12, 40 (%rdi) ++ mov %r13, 48 (%rdi) ++ mov %r14, 56 (%rdi) ++ ++ lea 64 (%rsi), %rsi ++ lea 64 (%rdi), %rdi ++ ++ jz L(prebail) ++ ++ dec %rcx ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %rbx ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ mov 32 (%rsi), %r11 ++ mov 40 (%rsi), %r12 ++ mov 48 (%rsi), %r13 ++ mov 56 (%rsi), %r14 ++ ++ prefetcht0 896 - 64 (%rdi) ++ prefetcht0 896 - 0 (%rdi) ++ ++ mov %rax, (%rdi) ++ mov %rbx, 8 (%rdi) ++ mov %r9, 16 (%rdi) ++ mov %r10, 24 (%rdi) ++ mov %r11, 32 (%rdi) ++ mov %r12, 40 (%rdi) ++ mov %r13, 48 (%rdi) ++ mov %r14, 56 (%rdi) ++ ++ lea 64 (%rsi), %rsi ++ lea 64 (%rdi), %rdi ++ ++ jnz L(preloop) ++ ++L(prebail): ++ pop %rbx ++ pop %r12 ++ pop %r13 ++ pop %r14 ++ ++# .p2align 4 ++ ++L(preskip): ++ sub %r8, %rdx # check for more ++ test $-64, %rdx ++ jnz L(preafter) ++ ++ and $63, %edx # check for left overs ++ jnz L(32) ++ ++ pop %rax ++ ret ++ ++ .p2align 4 ++ ++L(preafter): ++ ++L(NTtry): ++ ++L(NT): # NT 128-byte ++ mov %rdx, %rcx ++ shr $7, %rcx ++ jz L(NTskip) ++ ++ push %r14 ++ push %r13 ++ push %r12 ++ ++ .p2align 4 ++ ++L(NTloop): ++ prefetchnta 768 (%rsi) ++ prefetchnta 832 (%rsi) ++ ++ dec %rcx ++ ++ mov (%rsi), %rax ++ mov 8 (%rsi), %r8 ++ mov 16 (%rsi), %r9 ++ mov 24 (%rsi), %r10 ++ mov 32 (%rsi), %r11 ++ mov 40 (%rsi), %r12 ++ mov 48 (%rsi), %r13 ++ mov 56 (%rsi), %r14 ++ ++ movnti %rax, (%rdi) ++ movnti %r8, 8 (%rdi) ++ movnti %r9, 16 (%rdi) ++ movnti %r10, 24 (%rdi) ++ movnti %r11, 32 (%rdi) ++ movnti %r12, 40 (%rdi) ++ movnti %r13, 48 (%rdi) ++ movnti %r14, 56 (%rdi) ++ ++ mov 64 (%rsi), %rax ++ mov 72 (%rsi), %r8 ++ mov 80 (%rsi), %r9 ++ mov 88 (%rsi), %r10 ++ mov 96 (%rsi), %r11 ++ mov 104 (%rsi), %r12 ++ mov 112 (%rsi), %r13 ++ mov 120 (%rsi), %r14 ++ ++ movnti %rax, 64 (%rdi) ++ movnti %r8, 72 (%rdi) ++ movnti %r9, 80 (%rdi) ++ movnti %r10, 88 (%rdi) ++ movnti %r11, 96 (%rdi) ++ movnti %r12, 104 (%rdi) ++ movnti %r13, 112 (%rdi) ++ movnti %r14, 120 (%rdi) ++ ++ lea 128 (%rsi), %rsi ++ lea 128 (%rdi), %rdi ++ ++ jnz L(NTloop) ++ ++ mfence # serialize memory operations ++ ++ pop %r12 ++ pop %r13 ++ pop %r14 ++ ++L(NTskip): ++ and $127, %edx # check for left overs ++ jnz L(32) ++ ++ pop %rax + ret + +-END (BP_SYM (memcpy)) +-#if !MEMPCPY_P ++END (memcpy) ++ ++#ifndef USE_AS_MEMPCPY + libc_hidden_builtin_def (memcpy) + #endif +--- glibc-head/libc/sysdeps/x86_64/mempcpy.S ++++ glibc-amd/libc/sysdeps/x86_64/mempcpy.S +@@ -1,3 +1,4 @@ ++#define USE_AS_MEMPCPY + #define memcpy __mempcpy + #define __memcpy_chk __mempcpy_chk + #include <sysdeps/x86_64/memcpy.S> +--- glibc-head/libc/sysdeps/x86_64/memset.S ++++ glibc-amd/libc/sysdeps/x86_64/memset.S +@@ -1,145 +1,322 @@ +-/* memset/bzero -- set memory area to CH/0 +- Optimized version for x86-64. +- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Andreas Jaeger <aj@suse.de>. +- +- 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. */ ++# (c) 2002 Advanced Micro Devices, Inc. ++# YOUR USE OF THIS CODE IS SUBJECT TO THE TERMS ++# AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++# LICENSE FOUND IN THE "README" FILE THAT IS ++# INCLUDED WITH THIS FILE + + #include <sysdep.h> + #include "asm-syntax.h" + #include "bp-sym.h" + #include "bp-asm.h" ++#if defined PIC && defined SHARED ++# include <rtld-global-offsets.h> ++#endif + +-/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */ +-#define BZERO_P (defined memset) +- +-/* This is somehow experimental and could made dependend on the cache +- size. */ +-#define LARGE $120000 ++#if defined PIC && defined SHARED ++ .globl _rtld_local_ro ++ .hidden _rtld_local_ro ++ .set _rtld_local_ro,_rtld_global_ro ++#endif + + .text +-#if !BZERO_P && defined PIC && !defined NOT_IN_libc ++#if !defined USE_AS_BZERO && defined PIC && !defined NOT_IN_libc + ENTRY (__memset_chk) + cmpq %rdx, %rcx + jb HIDDEN_JUMPTARGET (__chk_fail) + END (__memset_chk) + #endif +-ENTRY (memset) +-#if BZERO_P +- mov %rsi,%rdx /* Adjust parameter. */ +- xorl %esi,%esi /* Fill with 0s. */ +-#endif +- cmp $0x7,%rdx /* Check for small length. */ +- mov %rdi,%rcx /* Save ptr as return value. */ +- jbe 7f + +-#if BZERO_P +- mov %rsi,%r8 /* Just copy 0. */ ++ENTRY (memset) # (void *, const void*, size_t) ++ ++#ifdef USE_AS_BZERO ++ mov %rsi, %rdx # memset doubles as bzero ++ xorl %esi, %esi ++#else ++ mov $0x0101010101010101, %rcx # memset is itself ++ movzx %sil, %rsi ++ imul %rcx, %rsi # replicate 8 times ++#endif ++ ++L(try1): # up to 64B ++ cmp $64, %rdx ++ mov %rdi, %rax # return memory block address (even for bzero ()) ++ jae L(1after) ++ ++L(1): # 1-byte loop ++ test $1, %dl ++ jz L(1a) ++ ++ mov %sil, (%rdi) ++ inc %rdi ++ ++L(1a): ++ test $2, %dl ++ jz L(1b) ++ ++ mov %si, (%rdi) ++ add $2, %rdi ++ ++L(1b): ++ test $4, %dl ++ jz L(1c) ++ ++ mov %esi, (%rdi) ++ add $4, %rdi ++ ++L(1c): ++ test $8, %dl ++ jz L(1d) ++ ++ mov %rsi, (%rdi) ++ add $8, %rdi ++ ++L(1d): ++ test $16, %dl ++ jz L(1e) ++ ++ mov %rsi, (%rdi) ++ mov %rsi, 8 (%rdi) ++ add $16, %rdi ++ ++L(1e): ++ test $32, %dl ++ jz L(1f) ++ ++ mov %rsi, (%rdi) ++ mov %rsi, 8 (%rdi) ++ mov %rsi, 16 (%rdi) ++ mov %rsi, 24 (%rdi) ++# add $32, %rdi ++ ++L(1f): ++ ++L(exit): ++ rep ++ ret ++ ++ .p2align 4 ++ ++L(1after): ++ ++L(32try): # up to 512B ++ cmp $512, %rdx ++ ja L(32after) ++ ++L(32): # 32-byte loop ++ mov %edx, %ecx ++ shr $5, %ecx ++ jz L(32skip) ++ ++ .p2align 4 ++ ++L(32loop): ++ dec %ecx ++ ++ mov %rsi, (%rdi) ++ mov %rsi, 8 (%rdi) ++ mov %rsi, 16 (%rdi) ++ mov %rsi, 24 (%rdi) ++ ++ lea 32 (%rdi), %rdi ++ ++ jz L(32skip) ++ ++ dec %ecx ++ ++ mov %rsi, (%rdi) ++ mov %rsi, 8 (%rdi) ++ mov %rsi, 16 (%rdi) ++ mov %rsi, 24 (%rdi) ++ ++ lea 32 (%rdi), %rdi ++ ++ jnz L(32loop) ++ ++ .p2align 4 ++ ++L(32skip): ++ and $31, %edx # check for left overs ++ jnz L(1) ++ ++ rep ++ ret ++ ++ .p2align 4 ++ ++L(32after): ++ ++L(aligntry): ++ mov %edi, %ecx # align by destination ++ ++ and $7, %ecx # skip if already aligned ++ jz L(alignafter) ++ ++L(align): # align loop ++ lea -8 (%rcx, %rdx), %rdx ++ sub $8, %ecx ++ ++ .p2align 4 ++ ++L(alignloop): ++ inc %ecx ++ ++ mov %sil, (%rdi) ++ lea 1 (%rdi), %rdi ++ ++ jnz L(alignloop) ++ ++ .p2align 4 ++ ++L(alignafter): ++ ++# For MP System half cache size is better, ++# for UP full cache size is better. ++# Use half cache size only. ++L(fasttry): # between 2KB and 1/2 L2 ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %r8 ++ mov RTLD_GLOBAL_DL_CACHE2SIZEHALF (%r8), %r8 + #else +- /* Populate 8 bit data to full 64-bit. */ +- movabs $0x0101010101010101,%r8 +- movzbl %sil,%eax +- imul %rax,%r8 +-#endif +- test $0x7,%edi /* Check for alignment. */ +- je 2f +- +- .p2align 4 +-1: /* Align ptr to 8 byte. */ +- mov %sil,(%rcx) +- dec %rdx +- inc %rcx +- test $0x7,%ecx +- jne 1b +- +-2: /* Check for really large regions. */ +- mov %rdx,%rax +- shr $0x6,%rax +- je 4f +- cmp LARGE, %rdx +- jae 11f +- +- .p2align 4 +-3: /* Copy 64 bytes. */ +- mov %r8,(%rcx) +- mov %r8,0x8(%rcx) +- mov %r8,0x10(%rcx) +- mov %r8,0x18(%rcx) +- mov %r8,0x20(%rcx) +- mov %r8,0x28(%rcx) +- mov %r8,0x30(%rcx) +- mov %r8,0x38(%rcx) +- add $0x40,%rcx +- dec %rax +- jne 3b +- +-4: /* Copy final bytes. */ +- and $0x3f,%edx +- mov %rdx,%rax +- shr $0x3,%rax +- je 6f +- +-5: /* First in chunks of 8 bytes. */ +- mov %r8,(%rcx) +- add $0x8,%rcx +- dec %rax +- jne 5b +-6: +- and $0x7,%edx +-7: +- test %rdx,%rdx +- je 9f +-8: /* And finally as bytes (up to 7). */ +- mov %sil,(%rcx) +- inc %rcx +- dec %rdx +- jne 8b +-9: +-#if BZERO_P +- nop ++ mov _dl_cache2sizehalf@GOTPCREL (%rip), %r8 ++ mov (%r8), %r8 ++# endif + #else +- /* Load result (only if used as memset). */ +- mov %rdi,%rax /* start address of destination is result */ ++ mov _dl_cache2sizehalf, %r8 + #endif +- retq ++ cmp %rdx, %r8 ++ cmova %rdx, %r8 ++ ++ cmp $2048, %rdx # this is slow for some block sizes ++ jb L(64) ++ ++L(fast): # microcode loop ++ mov %r8, %rcx ++ and $-8, %r8 ++ shr $3, %rcx ++ ++ xchg %rax, %rsi ++ ++ rep ++ stosq ++ ++ xchg %rax, %rsi ++ ++L(fastskip): ++ sub %r8, %rdx # check for more ++ ja L(64after) ++ ++ and $7, %edx # check for left overs ++ jnz L(1) ++ ++ rep ++ ret + + .p2align 4 +-11: /* Copy 64 bytes without polluting the cache. */ +- /* We could use movntdq %xmm0,(%rcx) here to further +- speed up for large cases but let's not use XMM registers. */ +- movnti %r8,(%rcx) +- movnti %r8,0x8(%rcx) +- movnti %r8,0x10(%rcx) +- movnti %r8,0x18(%rcx) +- movnti %r8,0x20(%rcx) +- movnti %r8,0x28(%rcx) +- movnti %r8,0x30(%rcx) +- movnti %r8,0x38(%rcx) +- add $0x40,%rcx +- dec %rax +- jne 11b +- jmp 4b ++ ++L(fastafter): ++ ++L(64try): # up to 2KB ++ ++L(64): # 64-byte loop ++ mov %r8, %rcx ++ and $-64, %r8 ++ shr $6, %rcx ++ ++ dec %rcx # this iteration starts the prefetcher sooner ++ ++ mov %rsi, (%rdi) ++ mov %rsi, 8 (%rdi) ++ mov %rsi, 16 (%rdi) ++ mov %rsi, 24 (%rdi) ++ mov %rsi, 32 (%rdi) ++ mov %rsi, 40 (%rdi) ++ mov %rsi, 48 (%rdi) ++ mov %rsi, 56 (%rdi) ++ ++ lea 64 (%rdi), %rdi ++ ++ .p2align 4 ++ ++L(64loop): ++ dec %rcx ++ ++ mov %rsi, (%rdi) ++ mov %rsi, 8 (%rdi) ++ mov %rsi, 16 (%rdi) ++ mov %rsi, 24 (%rdi) ++ mov %rsi, 32 (%rdi) ++ mov %rsi, 40 (%rdi) ++ mov %rsi, 48 (%rdi) ++ mov %rsi, 56 (%rdi) ++ ++ lea 64 (%rdi), %rdi ++ ++ jnz L(64loop) ++ ++L(64skip): ++ sub %r8, %rdx # check for more ++ ja L(64after) ++ ++ and $63, %edx # check for left overs ++ jnz L(32) ++ ++ rep ++ ret ++ ++ .p2align 4 ++ ++L(64after): ++ ++L(NTtry): ++ ++L(NT): # 128-byte NT loop ++ mov %rdx, %rcx ++ shr $7, %rcx ++ jz L(NTskip) ++ ++ .p2align 4 ++ ++L(NTloop): # on an MP system it would be better to prefetchnta 320 (%rdi) and 384 (%rdi) here, but not so on an 1P system ++ dec %rcx ++ ++ movnti %rsi, (%rdi) ++ movnti %rsi, 8 (%rdi) ++ movnti %rsi, 16 (%rdi) ++ movnti %rsi, 24 (%rdi) ++ movnti %rsi, 32 (%rdi) ++ movnti %rsi, 40 (%rdi) ++ movnti %rsi, 48 (%rdi) ++ movnti %rsi, 56 (%rdi) ++ movnti %rsi, 64 (%rdi) ++ movnti %rsi, 72 (%rdi) ++ movnti %rsi, 80 (%rdi) ++ movnti %rsi, 88 (%rdi) ++ movnti %rsi, 96 (%rdi) ++ movnti %rsi, 104 (%rdi) ++ movnti %rsi, 112 (%rdi) ++ movnti %rsi, 120 (%rdi) ++ ++ lea 128 (%rdi), %rdi ++ ++ jnz L(NTloop) ++ ++ mfence # serialize memory operations ++ ++L(NTskip): ++ and $127, %edx # check for left overs ++ jnz L(32) ++ ++ rep ++ ret + + END (memset) +-#if !BZERO_P ++ ++#ifndef USE_AS_BZERO + libc_hidden_builtin_def (memset) + #endif + +-#if !BZERO_P && defined PIC && !defined NOT_IN_libc ++#if !defined USE_AS_BZERO && defined PIC && !defined NOT_IN_libc + strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" +--- glibc-head/libc/sysdeps/x86_64/stpcpy.S ++++ glibc-amd/libc/sysdeps/x86_64/stpcpy.S +@@ -1,5 +1,5 @@ + #define USE_AS_STPCPY +-#define STRCPY __stpcpy ++#define strcpy __stpcpy + + #include <sysdeps/x86_64/strcpy.S> + +--- glibc-head/libc/sysdeps/x86_64/stpncpy.S ++++ glibc-amd/libc/sysdeps/x86_64/stpncpy.S +@@ -0,0 +1,9 @@ ++#define USE_AS_STRNCPY ++#define USE_AS_STPCPY ++#define strcpy __stpncpy ++ ++#include <sysdeps/x86_64/strcpy.S> ++ ++weak_alias (__stpncpy, stpncpy) ++libc_hidden_def (__stpncpy) ++libc_hidden_builtin_def (stpncpy) +--- glibc-head/libc/sysdeps/x86_64/strcpy.S ++++ glibc-amd/libc/sysdeps/x86_64/strcpy.S +@@ -1,159 +1,1141 @@ +-/* strcpy/stpcpy implementation for x86-64. +- Copyright (C) 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Andreas Jaeger <aj@suse.de>, 2002. +- +- 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 <sysdep.h> +-#include "asm-syntax.h" +-#include "bp-sym.h" +-#include "bp-asm.h" ++# (c) 2002 Advanced Micro Devices, Inc. ++# YOUR USE OF THIS CODE IS SUBJECT TO THE TERMS ++# AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++# LICENSE FOUND IN THE "README" FILE THAT IS ++# INCLUDED WITH THIS FILE ++ ++#include "sysdep.h" ++#if defined PIC && defined SHARED ++# include <rtld-global-offsets.h> ++#endif + +-#ifndef USE_AS_STPCPY +-# define STRCPY strcpy ++#if defined PIC && defined SHARED ++ .globl _rtld_local_ro ++ .hidden _rtld_local_ro ++ .set _rtld_local_ro,_rtld_global_ro + #endif + + .text +-ENTRY (BP_SYM (STRCPY)) +- movq %rsi, %rcx /* Source register. */ +- andl $7, %ecx /* mask alignment bits */ +- movq %rdi, %rdx /* Duplicate destination pointer. */ +- +- jz 5f /* aligned => start loop */ +- +- neg %ecx /* We need to align to 8 bytes. */ +- addl $8,%ecx +- /* Search the first bytes directly. */ +-0: +- movb (%rsi), %al /* Fetch a byte */ +- testb %al, %al /* Is it NUL? */ +- movb %al, (%rdx) /* Store it */ +- jz 4f /* If it was NUL, done! */ +- incq %rsi +- incq %rdx +- decl %ecx +- jnz 0b +- +-5: +- movq $0xfefefefefefefeff,%r8 +- +- /* Now the sources is aligned. Unfortunatly we cannot force +- to have both source and destination aligned, so ignore the +- alignment of the destination. */ ++ ++ENTRY (strcpy) # (char *, const char *) ++ ++#ifdef USE_AS_STRNCPY // (char *, const char *, size_t) ++ test %rdx, %rdx ++ mov %rdx, %r11 ++ jz L(exit) # early exit ++#endif ++ ++ xor %edx, %edx ++ ++L(aligntry): # between 0 and 7 bytes ++ mov %rsi, %r8 # align by source ++ and $7, %r8 ++ jz L(alignafter) ++ ++L(align): # 8-byte align ++ sub $8, %r8 ++ + .p2align 4 +-1: +- /* 1st unroll. */ +- movq (%rsi), %rax /* Read double word (8 bytes). */ +- addq $8, %rsi /* Adjust pointer for next word. */ +- movq %rax, %r9 /* Save a copy for NUL finding. */ +- addq %r8, %r9 /* add the magic value to the word. We get +- carry bits reported for each byte which +- is *not* 0 */ +- jnc 3f /* highest byte is NUL => return pointer */ +- xorq %rax, %r9 /* (word+magic)^word */ +- orq %r8, %r9 /* set all non-carry bits */ +- incq %r9 /* add 1: if one carry bit was *not* set +- the addition will not result in 0. */ +- +- jnz 3f /* found NUL => return pointer */ +- +- movq %rax, (%rdx) /* Write value to destination. */ +- addq $8, %rdx /* Adjust pointer. */ +- +- /* 2nd unroll. */ +- movq (%rsi), %rax /* Read double word (8 bytes). */ +- addq $8, %rsi /* Adjust pointer for next word. */ +- movq %rax, %r9 /* Save a copy for NUL finding. */ +- addq %r8, %r9 /* add the magic value to the word. We get +- carry bits reported for each byte which +- is *not* 0 */ +- jnc 3f /* highest byte is NUL => return pointer */ +- xorq %rax, %r9 /* (word+magic)^word */ +- orq %r8, %r9 /* set all non-carry bits */ +- incq %r9 /* add 1: if one carry bit was *not* set +- the addition will not result in 0. */ +- +- jnz 3f /* found NUL => return pointer */ +- +- movq %rax, (%rdx) /* Write value to destination. */ +- addq $8, %rdx /* Adjust pointer. */ +- +- /* 3rd unroll. */ +- movq (%rsi), %rax /* Read double word (8 bytes). */ +- addq $8, %rsi /* Adjust pointer for next word. */ +- movq %rax, %r9 /* Save a copy for NUL finding. */ +- addq %r8, %r9 /* add the magic value to the word. We get +- carry bits reported for each byte which +- is *not* 0 */ +- jnc 3f /* highest byte is NUL => return pointer */ +- xorq %rax, %r9 /* (word+magic)^word */ +- orq %r8, %r9 /* set all non-carry bits */ +- incq %r9 /* add 1: if one carry bit was *not* set +- the addition will not result in 0. */ +- +- jnz 3f /* found NUL => return pointer */ +- +- movq %rax, (%rdx) /* Write value to destination. */ +- addq $8, %rdx /* Adjust pointer. */ +- +- /* 4th unroll. */ +- movq (%rsi), %rax /* Read double word (8 bytes). */ +- addq $8, %rsi /* Adjust pointer for next word. */ +- movq %rax, %r9 /* Save a copy for NUL finding. */ +- addq %r8, %r9 /* add the magic value to the word. We get +- carry bits reported for each byte which +- is *not* 0 */ +- jnc 3f /* highest byte is NUL => return pointer */ +- xorq %rax, %r9 /* (word+magic)^word */ +- orq %r8, %r9 /* set all non-carry bits */ +- incq %r9 /* add 1: if one carry bit was *not* set +- the addition will not result in 0. */ +- +- jnz 3f /* found NUL => return pointer */ +- +- movq %rax, (%rdx) /* Write value to destination. */ +- addq $8, %rdx /* Adjust pointer. */ +- jmp 1b /* Next iteration. */ + +- /* Do the last few bytes. %rax contains the value to write. +- The loop is unrolled twice. */ ++L(alignloop): ++ movzbl (%rsi, %rdx), %eax ++ test %al, %al # check if character a NUL ++ mov %al, (%rdi, %rdx) ++ jz L(exit) ++ ++ inc %edx ++ ++#ifdef USE_AS_STRNCPY ++ dec %r11 ++ jz L(exit) ++#endif ++ ++ inc %r8 ++ jnz L(alignloop) ++ ++ .p2align 4,, 7 ++ ++L(alignafter): ++ ++L(8try): # up to 64 bytes ++ mov $0xfefefefefefefeff, %rcx ++ ++L(8): # 8-byte loop ++ ++L(8loop): ++#ifdef USE_AS_STRNCPY ++ sub $8, %r11 ++ jbe L(tail) ++#endif ++ ++ mov (%rsi, %rdx), %rax ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ jnc L(tail) # sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ inc %r8 # sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++ add $8, %edx ++ ++L(8after): # up to 64 bytes ++ ++L(64try): # up to 1/2 L1 ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %r9 ++ mov RTLD_GLOBAL_DL_CACHE1SIZEHALF (%r9), %r9 ++# else ++ mov _dl_cache1sizehalf@GOTPCREL (%rip), %r9 ++ mov (%r9), %r9 ++# endif ++#else ++ mov _dl_cache1sizehalf, %r9 ++#endif ++ ++L(64): # 64-byte loop ++ + .p2align 4 +-3: +- /* Note that stpcpy needs to return with the value of the NUL +- byte. */ +- movb %al, (%rdx) /* 1st byte. */ +- testb %al, %al /* Is it NUL. */ +- jz 4f /* yes, finish. */ +- incq %rdx /* Increment destination. */ +- movb %ah, (%rdx) /* 2nd byte. */ +- testb %ah, %ah /* Is it NUL?. */ +- jz 4f /* yes, finish. */ +- incq %rdx /* Increment destination. */ +- shrq $16, %rax /* Shift... */ +- jmp 3b /* and look at next two bytes in %rax. */ + +-4: ++L(64loop): ++#ifdef USE_AS_STRNCPY ++ sub $8, %r11 ++ jbe L(tail) ++#endif ++ ++ mov (%rsi, %rdx), %rax ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++ add $8, %edx ++ ++ cmp %r9, %rdx ++ jbe L(64loop) ++ ++L(64after): # up to 1/2 L1 ++ ++L(pretry): # up to 1/2 L2 ++#ifdef PIC ++# ifdef SHARED ++ mov _rtld_local_ro@GOTPCREL (%rip), %r9 ++ cmpl $0, RTLD_GLOBAL_DL_PREFETCHW (%r9) ++ mov RTLD_GLOBAL_DL_CACHE2SIZEHALF (%r9), %r9 ++# else ++ mov _dl_prefetchw@GOTPCREL (%rip), %r9 ++ cmpl $0, (%r9) ++ mov _dl_cache2sizehalf@GOTPCREL (%rip), %r9 ++ mov (%r9), %r9 ++# endif ++#else ++ cmpl $0, _dl_prefetchw ++ mov _dl_cache2sizehalf, %r9 ++#endif ++ jz L(preloop) # check for availability of PREFETCHW ++ ++ .p2align 4 ++ ++L(prewloop): # 64-byte with prefetching to state M ++#ifdef USE_AS_STRNCPY ++ sub $8, %r11 ++ jbe L(tail) ++#endif ++ ++ mov (%rsi, %rdx), %rax ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++ prefetchw 512 + 8 (%rdi, %rdx) ++ prefetcht0 512 + 8 (%rsi, %rdx) ++ ++ add $8, %edx ++ ++ cmp %r9, %rdx ++ jb L(prewloop) ++ jmp L(preafter) ++ ++L(prewafter): # up to 1/2 L2 ++ ++ .p2align 4 ++ ++L(preloop): # 64-byte with prefetching to state E ++#ifdef USE_AS_STRNCPY ++ sub $8, %r11 ++ jbe L(tail) ++#endif ++ ++ mov (%rsi, %rdx), %rax ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %edx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %edx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(tail) ++ ++ mov %rax, (%rdi, %rdx) ++ ++ prefetcht0 512 + 8 (%rdi, %rdx) ++ prefetcht0 512 + 8 (%rsi, %rdx) ++ ++ add $8, %edx ++ ++ cmp %r9, %rdx ++ jb L(preloop) ++ ++ .p2align 4 ++ ++L(preafter): # up to 1/2 of L2 ++ ++L(NTtry): ++ mfence ++ ++L(NT): # 64-byte NT ++ ++ .p2align 4 ++ ++L(NTloop): ++#ifdef USE_AS_STRNCPY ++ sub $8, %r11 ++ jbe L(tail) ++#endif ++ ++ mov (%rsi, %rdx), %rax ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++#ifdef USE_AS_STRNCPY ++ add $8, %rdx ++ ++ sub $8, %r11 ++ jbe L(tail) ++ ++ mov (%rsi, %rdx), %rax ++#else ++ mov 8 (%rsi, %rdx), %rax ++ add $8, %rdx ++#endif ++ ++ mov %rcx, %r8 ++ add %rax, %r8 ++ sbb %r10, %r10 ++ ++ xor %rax, %r8 ++ or %rcx, %r8 ++ sub %r10, %r8 ++ jnz L(NTtail) ++ ++ movnti %rax, (%rdi, %rdx) ++ ++ prefetchnta 768 + 8 (%rsi, %rdx) ++ ++ add $8, %rdx ++ jmp L(NTloop) ++ ++ .p2align 4 ++ ++L(NTtail): ++ mfence # serialize memory operations ++ ++ .p2align 4 ++ ++L(NTafter): ++ ++L(tailtry): ++ ++L(tail): # 1-byte tail ++#ifdef USE_AS_STRNCPY ++ add $8, %r11 ++ jz L(exit) ++#endif ++ ++ .p2align 4 ++ ++L(tailloop): ++ movzbl (%rsi, %rdx), %eax ++ test %al, %al ++ mov %al, (%rdi, %rdx) ++ jz L(exit) ++ ++ inc %rdx ++ ++#ifdef USE_AS_STRNCPY ++ dec %r11 ++ jz L(exit) ++#endif ++ jmp L(tailloop) ++ ++ .p2align 4 ++ ++L(tailafter): ++ ++L(exit): ++#ifdef USE_AS_STPCPY ++ lea (%rdi, %rdx), %rax ++#else ++ mov %rdi, %rax ++#endif ++ ++#ifdef USE_AS_STRNCPY ++ test %r11, %r11 ++ mov %r11, %rcx ++ jnz 2f ++ ++ rep ++ ret ++ ++ .p2align 4 ++ ++2: + #ifdef USE_AS_STPCPY +- movq %rdx, %rax /* Destination is return value. */ ++ mov %rax, %r8 + #else +- movq %rdi, %rax /* Source is return value. */ ++ mov %rdi, %r8 ++# endif ++ ++ xor %eax, %eax # bzero () would do too, but usually there are only a handfull of bytes left ++ shr $3, %rcx ++ lea (%rdi, %rdx), %rdi ++ jz 3f ++ ++ rep stosq ++ ++ and $7, %r11d ++ jz 1f ++ ++ .p2align 4,, 4 ++ ++3: ++ mov %al, (%rdi) ++ inc %rdi ++ ++ dec %r11d ++ jnz 3b ++ ++ .p2align 4,, 4 ++ ++1: ++ mov %r8, %rax + #endif +- retq +-END (BP_SYM (STRCPY)) +-#ifndef USE_AS_STPCPY ++ ret ++ ++END (strcpy) ++ ++#if !defined USE_AS_STPCPY && !defined USE_AS_STRNCPY + libc_hidden_builtin_def (strcpy) + #endif +--- glibc-head/libc/sysdeps/x86_64/strncpy.S ++++ glibc-amd/libc/sysdeps/x86_64/strncpy.S +@@ -0,0 +1,8 @@ ++#define USE_AS_STRNCPY ++#define strcpy __strncpy ++ ++#include <sysdeps/x86_64/strcpy.S> ++ ++weak_alias (__strncpy, strncpy) ++libc_hidden_def (__strncpy) ++libc_hidden_builtin_def (strncpy) diff --git a/patches/glibc-2.5/generic/gentoo/6901_all_2.4-new-libm-20060321.patch b/patches/glibc-2.5/generic/gentoo/6901_all_2.4-new-libm-20060321.patch new file mode 100644 index 0000000..f8ca007 --- /dev/null +++ b/patches/glibc-2.5/generic/gentoo/6901_all_2.4-new-libm-20060321.patch @@ -0,0 +1,12735 @@ +http://sourceware.org/ml/libc-alpha/2006-03/msg00147.html + +diff -urpN libc/sysdeps/x86_64/fpu/e_acos.c libc-amd/sysdeps/x86_64/fpu/e_acos.c +--- libc/sysdeps/x86_64/fpu/e_acos.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_acos.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_acosf.c libc-amd/sysdeps/x86_64/fpu/e_acosf.c +--- libc/sysdeps/x86_64/fpu/e_acosf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_acosf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_asin.c libc-amd/sysdeps/x86_64/fpu/e_asin.c +--- libc/sysdeps/x86_64/fpu/e_asin.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_asin.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_asinf.c libc-amd/sysdeps/x86_64/fpu/e_asinf.c +--- libc/sysdeps/x86_64/fpu/e_asinf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_asinf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_exp10.c libc-amd/sysdeps/x86_64/fpu/e_exp10.c +--- libc/sysdeps/x86_64/fpu/e_exp10.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_exp10.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_exp10f.c libc-amd/sysdeps/x86_64/fpu/e_exp10f.c +--- libc/sysdeps/x86_64/fpu/e_exp10f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_exp10f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_exp2.c libc-amd/sysdeps/x86_64/fpu/e_exp2.c +--- libc/sysdeps/x86_64/fpu/e_exp2.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_exp2.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_exp2f.c libc-amd/sysdeps/x86_64/fpu/e_exp2f.c +--- libc/sysdeps/x86_64/fpu/e_exp2f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_exp2f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_exp.c libc-amd/sysdeps/x86_64/fpu/e_exp.c +--- libc/sysdeps/x86_64/fpu/e_exp.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_exp.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_expf.c libc-amd/sysdeps/x86_64/fpu/e_expf.c +--- libc/sysdeps/x86_64/fpu/e_expf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_expf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_fmod.c libc-amd/sysdeps/x86_64/fpu/e_fmod.c +--- libc/sysdeps/x86_64/fpu/e_fmod.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_fmod.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_fmodf.c libc-amd/sysdeps/x86_64/fpu/e_fmodf.c +--- libc/sysdeps/x86_64/fpu/e_fmodf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_fmodf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_hypot.c libc-amd/sysdeps/x86_64/fpu/e_hypot.c +--- libc/sysdeps/x86_64/fpu/e_hypot.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_hypot.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_hypotf.c libc-amd/sysdeps/x86_64/fpu/e_hypotf.c +--- libc/sysdeps/x86_64/fpu/e_hypotf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_hypotf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_log10.c libc-amd/sysdeps/x86_64/fpu/e_log10.c +--- libc/sysdeps/x86_64/fpu/e_log10.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_log10.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_log10f.c libc-amd/sysdeps/x86_64/fpu/e_log10f.c +--- libc/sysdeps/x86_64/fpu/e_log10f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_log10f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_log2.c libc-amd/sysdeps/x86_64/fpu/e_log2.c +--- libc/sysdeps/x86_64/fpu/e_log2.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_log2.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_log2f.c libc-amd/sysdeps/x86_64/fpu/e_log2f.c +--- libc/sysdeps/x86_64/fpu/e_log2f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_log2f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_log.c libc-amd/sysdeps/x86_64/fpu/e_log.c +--- libc/sysdeps/x86_64/fpu/e_log.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_log.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_logf.c libc-amd/sysdeps/x86_64/fpu/e_logf.c +--- libc/sysdeps/x86_64/fpu/e_logf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_logf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_pow.c libc-amd/sysdeps/x86_64/fpu/e_pow.c +--- libc/sysdeps/x86_64/fpu/e_pow.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_pow.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_powf.c libc-amd/sysdeps/x86_64/fpu/e_powf.c +--- libc/sysdeps/x86_64/fpu/e_powf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_powf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_remainder.c libc-amd/sysdeps/x86_64/fpu/e_remainder.c +--- libc/sysdeps/x86_64/fpu/e_remainder.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_remainder.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_remainderf.c libc-amd/sysdeps/x86_64/fpu/e_remainderf.c +--- libc/sysdeps/x86_64/fpu/e_remainderf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_remainderf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_sinh.c libc-amd/sysdeps/x86_64/fpu/e_sinh.c +--- libc/sysdeps/x86_64/fpu/e_sinh.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_sinh.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/e_sinhf.c libc-amd/sysdeps/x86_64/fpu/e_sinhf.c +--- libc/sysdeps/x86_64/fpu/e_sinhf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/e_sinhf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/libm_amd.h libc-amd/sysdeps/x86_64/fpu/libm_amd.h +--- libc/sysdeps/x86_64/fpu/libm_amd.h 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/libm_amd.h 2006-03-22 02:42:25.000000000 +0100 +@@ -0,0 +1,23 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#ifndef LIBM_AMD_H_INCLUDED ++#define LIBM_AMD_H_INCLUDED 1 ++ ++#include <math.h> ++ ++extern double chgsign(double x); ++extern float chgsignf(float x); ++ ++extern double fma(double x, double y, double z); ++extern float fmaf(float x, float y, float z); ++ ++extern void __remainder_piby2(double x, double *r, double *rr, int *region); ++extern void __remainder_piby2f(float x, double *r, int *region); ++ ++#endif /* LIBM_AMD_H_INCLUDED */ +diff -urpN libc/sysdeps/x86_64/fpu/libm_inlines_amd.h libc-amd/sysdeps/x86_64/fpu/libm_inlines_amd.h +--- libc/sysdeps/x86_64/fpu/libm_inlines_amd.h 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/libm_inlines_amd.h 2006-03-22 02:35:00.000000000 +0100 +@@ -0,0 +1,2260 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#ifndef LIBM_INLINES_AMD_H_INCLUDED ++#define LIBM_INLINES_AMD_H_INCLUDED 1 ++ ++#include "libm_util_amd.h" ++ ++#ifdef WIN32 ++#define inline __inline ++#endif ++ ++/* Set defines for inline functions calling other inlines */ ++#if defined(USE_VAL_WITH_FLAGS) || defined(USE_VALF_WITH_FLAGS) || \ ++ defined(USE_ZERO_WITH_FLAGS) || defined(USE_ZEROF_WITH_FLAGS) || \ ++ defined(USE_NAN_WITH_FLAGS) || defined(USE_NANF_WITH_FLAGS) || \ ++ defined(USE_INFINITY_WITH_FLAGS) || defined(USE_INFINITYF_WITH_FLAGS) || \ ++ defined(USE_SQRT_AMD_INLINE) || defined(USE_SQRTF_AMD_INLINE) ++#undef USE_RAISE_FPSW_FLAGS ++#define USE_RAISE_FPSW_FLAGS 1 ++#endif ++ ++#if defined(USE_SPLITDOUBLE) ++/* Splits double x into exponent e and mantissa m, where 0.5 <= abs(m) < 1.0. ++ Assumes that x is not zero, denormal, infinity or NaN, but these conditions ++ are not checked */ ++static inline void splitDouble(double x, int *e, double *m) ++{ ++ unsigned long ux, uy; ++ GET_BITS_DP64(x, ux); ++ uy = ux; ++ ux &= EXPBITS_DP64; ++ ux >>= EXPSHIFTBITS_DP64; ++ *e = (int)ux - EXPBIAS_DP64 + 1; ++ uy = (uy & (SIGNBIT_DP64 | MANTBITS_DP64)) | HALFEXPBITS_DP64; ++ PUT_BITS_DP64(uy, x); ++ *m = x; ++} ++#endif /* USE_SPLITDOUBLE */ ++ ++ ++#if defined(USE_SPLITDOUBLE_2) ++/* Splits double x into exponent e and mantissa m, where 1.0 <= abs(m) < 4.0. ++ Assumes that x is not zero, denormal, infinity or NaN, but these conditions ++ are not checked. Also assumes EXPBIAS_DP is odd. With this ++ assumption, e will be even on exit. */ ++static inline void splitDouble_2(double x, int *e, double *m) ++{ ++ unsigned long ux, vx; ++ GET_BITS_DP64(x, ux); ++ vx = ux; ++ ux &= EXPBITS_DP64; ++ ux >>= EXPSHIFTBITS_DP64; ++ if (ux & 1) ++ { ++ /* The exponent is odd */ ++ vx = (vx & (SIGNBIT_DP64 | MANTBITS_DP64)) | ONEEXPBITS_DP64; ++ PUT_BITS_DP64(vx, x); ++ *m = x; ++ *e = ux - EXPBIAS_DP64; ++ } ++ else ++ { ++ /* The exponent is even */ ++ vx = (vx & (SIGNBIT_DP64 | MANTBITS_DP64)) | TWOEXPBITS_DP64; ++ PUT_BITS_DP64(vx, x); ++ *m = x; ++ *e = ux - EXPBIAS_DP64 - 1; ++ } ++} ++#endif /* USE_SPLITDOUBLE_2 */ ++ ++ ++#if defined(USE_SPLITFLOAT) ++/* Splits float x into exponent e and mantissa m, where 0.5 <= abs(m) < 1.0. ++ Assumes that x is not zero, denormal, infinity or NaN, but these conditions ++ are not checked */ ++static inline void splitFloat(float x, int *e, float *m) ++{ ++ unsigned int ux, uy; ++ GET_BITS_SP32(x, ux); ++ uy = ux; ++ ux &= EXPBITS_SP32; ++ ux >>= EXPSHIFTBITS_SP32; ++ *e = (int)ux - EXPBIAS_SP32 + 1; ++ uy = (uy & (SIGNBIT_SP32 | MANTBITS_SP32)) | HALFEXPBITS_SP32; ++ PUT_BITS_SP32(uy, x); ++ *m = x; ++} ++#endif /* USE_SPLITFLOAT */ ++ ++ ++#if defined(USE_SCALEDOUBLE_1) ++/* Scales the double x by 2.0**n. ++ Assumes EMIN <= n <= EMAX, though this condition is not checked. */ ++static inline double scaleDouble_1(double x, int n) ++{ ++ double t; ++ /* Construct the number t = 2.0**n */ ++ PUT_BITS_DP64(((long)n + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t); ++ return x*t; ++} ++#endif /* USE_SCALEDOUBLE_1 */ ++ ++ ++#if defined(USE_SCALEDOUBLE_2) ++/* Scales the double x by 2.0**n. ++ Assumes 2*EMIN <= n <= 2*EMAX, though this condition is not checked. */ ++static inline double scaleDouble_2(double x, int n) ++{ ++ double t1, t2; ++ int n1, n2; ++ n1 = n / 2; ++ n2 = n - n1; ++ /* Construct the numbers t1 = 2.0**n1 and t2 = 2.0**n2 */ ++ PUT_BITS_DP64(((long)n1 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t1); ++ PUT_BITS_DP64(((long)n2 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t2); ++ return (x*t1)*t2; ++} ++#endif /* USE_SCALEDOUBLE_2 */ ++ ++ ++#if defined(USE_SCALEDOUBLE_3) ++/* Scales the double x by 2.0**n. ++ Assumes 3*EMIN <= n <= 3*EMAX, though this condition is not checked. */ ++static inline double scaleDouble_3(double x, int n) ++{ ++ double t1, t2, t3; ++ int n1, n2, n3; ++ n1 = n / 3; ++ n2 = (n - n1) / 2; ++ n3 = n - n1 - n2; ++ /* Construct the numbers t1 = 2.0**n1, t2 = 2.0**n2 and t3 = 2.0**n3 */ ++ PUT_BITS_DP64(((long)n1 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t1); ++ PUT_BITS_DP64(((long)n2 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t2); ++ PUT_BITS_DP64(((long)n3 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, t3); ++ return ((x*t1)*t2)*t3; ++} ++#endif /* USE_SCALEDOUBLE_3 */ ++ ++ ++#if defined(USE_SCALEFLOAT_1) ++/* Scales the float x by 2.0**n. ++ Assumes EMIN <= n <= EMAX, though this condition is not checked. */ ++static inline double scaleFloat_1(float x, int n) ++{ ++ float t; ++ /* Construct the number t = 2.0**n */ ++ PUT_BITS_SP32((n + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t); ++ return x*t; ++} ++#endif /* USE_SCALEFLOAT_1 */ ++ ++ ++#if defined(USE_SCALEFLOAT_2) ++/* Scales the float x by 2.0**n. ++ Assumes 2*EMIN <= n <= 2*EMAX, though this condition is not checked. */ ++static inline float scaleFloat_2(float x, int n) ++{ ++ float t1, t2; ++ int n1, n2; ++ n1 = n / 2; ++ n2 = n - n1; ++ /* Construct the numbers t1 = 2.0**n1 and t2 = 2.0**n2 */ ++ PUT_BITS_SP32((n1 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t1); ++ PUT_BITS_SP32((n2 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t2); ++ return (x*t1)*t2; ++} ++#endif /* USE_SCALEFLOAT_2 */ ++ ++ ++#if defined(USE_SCALEFLOAT_3) ++/* Scales the float x by 2.0**n. ++ Assumes 3*EMIN <= n <= 3*EMAX, though this condition is not checked. */ ++static inline double scaleFloat_3(float x, int n) ++{ ++ float t1, t2, t3; ++ int n1, n2, n3; ++ n1 = n / 3; ++ n2 = (n - n1) / 2; ++ n3 = n - n1 - n2; ++ /* Construct the numbers t1 = 2.0**n1, t2 = 2.0**n2 and t3 = 2.0**n3 */ ++ PUT_BITS_SP32((n1 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t1); ++ PUT_BITS_SP32((n2 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t2); ++ PUT_BITS_SP32((n3 + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, t3); ++ return ((x*t1)*t2)*t3; ++} ++#endif /* USE_SCALEFLOAT_3 */ ++ ++#if defined(USE_SETPRECISIONDOUBLE) ++unsigned int setPrecisionDouble(void) ++{ ++ unsigned int cw, cwold = 0; ++#if defined(WIN32) ++ __asm fstcw cwold; ++ cw = cwold & (~0x00000300); /* These two bits control rounding precision */ ++ cw |= AMD_F_DOUBLE; ++ __asm fldcw cw; ++#elif defined(linux) ++ /* There is no precision control on Hammer */ ++#else ++ /* Do nowt */ ++#endif ++ return cwold; ++} ++#endif /* USE_SETPRECISIONDOUBLE */ ++ ++#if defined(USE_RESTOREPRECISION) ++void restorePrecision(unsigned int cwold) ++{ ++#if defined(WIN32) ++ __asm fldcw cwold; ++#elif defined(linux) ++ /* There is no precision control on Hammer */ ++#else ++ /* Do nowt */ ++#endif ++ return; ++} ++#endif /* USE_RESTOREPRECISION */ ++ ++ ++#if defined(USE_CLEAR_FPSW_FLAGS) ++/* Clears floating-point status flags. The argument should be ++ the bitwise or of the flags to be cleared, from the ++ list above, e.g. ++ clear_fpsw_flags(AMD_F_INEXACT | AMD_F_INVALID); ++ */ ++static inline void clear_fpsw_flags(int flags) ++{ ++#if defined(WIN32) ++ fpenv_type fenv; ++ /* Get the current floating-point environment */ ++ __asm fnstenv fenv; ++ fenv.status_word &= (~flags); ++ /* Put the floating-point environment back */ ++ __asm fldenv fenv; ++#elif defined(linux) ++ unsigned int cw; ++ /* Get the current floating-point control/status word */ ++ asm volatile ("STMXCSR %0" : "=m" (cw)); ++ cw &= (~flags); ++ asm volatile ("LDMXCSR %0" : : "m" (cw)); ++#else ++#error Unknown OS ++#endif ++} ++#endif /* USE_CLEAR_FPSW_FLAGS */ ++ ++ ++#if defined(USE_RAISE_FPSW_FLAGS) ++/* Raises floating-point status flags. The argument should be ++ the bitwise or of the flags to be raised, from the ++ list above, e.g. ++ raise_fpsw_flags(AMD_F_INEXACT | AMD_F_INVALID); ++ */ ++static inline void raise_fpsw_flags(int flags) ++{ ++#if defined(WIN32) ++ fpenv_type fenv; ++ /* Get the current floating-point environment */ ++ __asm fnstenv fenv; ++ fenv.status_word |= flags; ++ /* Put the floating-point environment back */ ++ __asm fldenv fenv; ++#elif defined(linux) ++ unsigned int cw; ++ /* Get the current floating-point control/status word */ ++ asm volatile ("STMXCSR %0" : "=m" (cw)); ++ cw |= flags; ++ asm volatile ("LDMXCSR %0" : : "m" (cw)); ++#else ++#error Unknown OS ++#endif ++} ++#endif /* USE_RAISE_FPSW_FLAGS */ ++ ++ ++#if defined(USE_GET_FPSW_INLINE) ++/* Return the current floating-point status word */ ++static inline unsigned int get_fpsw_inline(void) ++{ ++#if defined(WIN32) ++ unsigned short sw; ++ __asm fstsw sw; ++ return (unsigned int)sw; ++#elif defined(linux) ++ unsigned int sw; ++ asm volatile ("STMXCSR %0" : "=m" (sw)); ++ return sw; ++#else ++#error Unknown OS ++#endif ++} ++#endif /* USE_GET_FPSW_INLINE */ ++ ++#if defined(USE_SET_FPSW_INLINE) ++/* Set the floating-point status word */ ++static inline void set_fpsw_inline(unsigned int sw) ++{ ++#if defined(WIN32) ++ fpenv_type fenv; ++ /* Get the current floating-point environment */ ++ __asm fnstenv fenv; ++ /* Set the status word to sw */ ++ fenv.status_word = (unsigned short)sw; ++ /* Put the floating-point environment back */ ++ __asm fldenv fenv; ++#elif defined(linux) ++ /* Set the current floating-point control/status word */ ++ asm volatile ("LDMXCSR %0" : : "m" (sw)); ++#else ++#error Unknown OS ++#endif ++} ++#endif /* USE_SET_FPSW_INLINE */ ++ ++#if defined(USE_CLEAR_FPSW_INLINE) ++/* Clear all exceptions from the floating-point status word */ ++static inline void clear_fpsw_inline(void) ++{ ++#if defined(WIN32) ++ fpenv_type fenv; ++ /* Get the current floating-point environment */ ++ __asm fnstenv fenv; ++ /* Set the status word to 0 */ ++ fenv.status_word = 0; ++ /* Put the floating-point environment back */ ++ __asm fldenv fenv; ++#elif defined(linux) ++ unsigned int cw; ++ /* Get the current floating-point control/status word */ ++ asm volatile ("STMXCSR %0" : "=m" (cw)); ++ cw &= ~(AMD_F_INEXACT | AMD_F_UNDERFLOW | AMD_F_OVERFLOW | ++ AMD_F_DIVBYZERO | AMD_F_INVALID); ++ asm volatile ("LDMXCSR %0" : : "m" (cw)); ++#else ++#error Unknown OS ++#endif ++} ++#endif /* USE_CLEAR_FPSW_INLINE */ ++ ++ ++#if defined(USE_VAL_WITH_FLAGS) ++/* Returns a double value after raising the given flags, ++ e.g. val_with_flags(AMD_F_INEXACT); ++ */ ++static inline double val_with_flags(double val, int flags) ++{ ++ raise_fpsw_flags(flags); ++ return val; ++} ++#endif /* USE_VAL_WITH_FLAGS */ ++ ++#if defined(USE_VALF_WITH_FLAGS) ++/* Returns a float value after raising the given flags, ++ e.g. valf_with_flags(AMD_F_INEXACT); ++ */ ++static inline float valf_with_flags(float val, int flags) ++{ ++ raise_fpsw_flags(flags); ++ return val; ++} ++#endif /* USE_VALF_WITH_FLAGS */ ++ ++ ++#if defined(USE_ZERO_WITH_FLAGS) ++/* Returns a double +zero after raising the given flags, ++ e.g. zero_with_flags(AMD_F_INEXACT | AMD_F_INVALID); ++ */ ++static inline double zero_with_flags(int flags) ++{ ++ raise_fpsw_flags(flags); ++ return 0.0; ++} ++#endif /* USE_ZERO_WITH_FLAGS */ ++ ++ ++#if defined(USE_ZEROF_WITH_FLAGS) ++/* Returns a float +zero after raising the given flags, ++ e.g. zerof_with_flags(AMD_F_INEXACT | AMD_F_INVALID); ++ */ ++static inline float zerof_with_flags(int flags) ++{ ++ raise_fpsw_flags(flags); ++ return 0.0F; ++} ++#endif /* USE_ZEROF_WITH_FLAGS */ ++ ++ ++#if defined(USE_NAN_WITH_FLAGS) ++/* Returns a double quiet +nan after raising the given flags, ++ e.g. nan_with_flags(AMD_F_INVALID); ++*/ ++static inline double nan_with_flags(int flags) ++{ ++ double z; ++ raise_fpsw_flags(flags); ++ PUT_BITS_DP64(0x7ff8000000000000, z); ++ return z; ++} ++#endif /* USE_NAN_WITH_FLAGS */ ++ ++#if defined(USE_NANF_WITH_FLAGS) ++/* Returns a float quiet +nan after raising the given flags, ++ e.g. nanf_with_flags(AMD_F_INVALID); ++*/ ++static inline float nanf_with_flags(int flags) ++{ ++ float z; ++ raise_fpsw_flags(flags); ++ PUT_BITS_SP32(0x7fc00000, z); ++ return z; ++} ++#endif /* USE_NANF_WITH_FLAGS */ ++ ++ ++#ifdef USE_INFINITY_WITH_FLAGS ++/* Returns a positive double infinity after raising the given flags, ++ e.g. infinity_with_flags(AMD_F_OVERFLOW); ++*/ ++static inline double infinity_with_flags(int flags) ++{ ++ double z; ++ raise_fpsw_flags(flags); ++ PUT_BITS_DP64((unsigned long)(BIASEDEMAX_DP64 + 1) << EXPSHIFTBITS_DP64, z); ++ return z; ++} ++#endif /* USE_INFINITY_WITH_FLAGS */ ++ ++#ifdef USE_INFINITYF_WITH_FLAGS ++/* Returns a positive float infinity after raising the given flags, ++ e.g. infinityf_with_flags(AMD_F_OVERFLOW); ++*/ ++static inline float infinityf_with_flags(int flags) ++{ ++ float z; ++ raise_fpsw_flags(flags); ++ PUT_BITS_SP32((BIASEDEMAX_SP32 + 1) << EXPSHIFTBITS_SP32, z); ++ return z; ++} ++#endif /* USE_INFINITYF_WITH_FLAGS */ ++ ++ ++#if defined(USE_SPLITEXP) ++/* Compute the values m, z1, and z2 such that base**x = 2**m * (z1 + z2). ++ Small arguments abs(x) < 1/(16*ln(base)) and extreme arguments ++ abs(x) > large/(ln(base)) (where large is the largest representable ++ floating point number) should be handled separately instead of calling ++ this function. This function is called by exp_amd, exp2_amd, exp10_amd, ++ cosh_amd and sinh_amd. */ ++static inline void splitexp(double x, double logbase, ++ double thirtytwo_by_logbaseof2, ++ double logbaseof2_by_32_lead, ++ double logbaseof2_by_32_trail, ++ int *m, double *z1, double *z2) ++{ ++ double q, r, r1, r2, f1, f2; ++ int n, j; ++ ++/* Arrays two_to_jby32_lead_table and two_to_jby32_trail_table contain ++ leading and trailing parts respectively of precomputed ++ values of pow(2.0,j/32.0), for j = 0, 1, ..., 31. ++ two_to_jby32_lead_table contains the first 25 bits of precision, ++ and two_to_jby32_trail_table contains a further 53 bits precision. */ ++ ++ static const double two_to_jby32_lead_table[32] = { ++ 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ ++ 1.02189713716506958008e+00, /* 0x3ff059b0d0000000 */ ++ 1.04427373409271240234e+00, /* 0x3ff0b55860000000 */ ++ 1.06714040040969848633e+00, /* 0x3ff11301d0000000 */ ++ 1.09050768613815307617e+00, /* 0x3ff172b830000000 */ ++ 1.11438673734664916992e+00, /* 0x3ff1d48730000000 */ ++ 1.13878858089447021484e+00, /* 0x3ff2387a60000000 */ ++ 1.16372483968734741211e+00, /* 0x3ff29e9df0000000 */ ++ 1.18920707702636718750e+00, /* 0x3ff306fe00000000 */ ++ 1.21524733304977416992e+00, /* 0x3ff371a730000000 */ ++ 1.24185776710510253906e+00, /* 0x3ff3dea640000000 */ ++ 1.26905095577239990234e+00, /* 0x3ff44e0860000000 */ ++ 1.29683953523635864258e+00, /* 0x3ff4bfdad0000000 */ ++ 1.32523661851882934570e+00, /* 0x3ff5342b50000000 */ ++ 1.35425549745559692383e+00, /* 0x3ff5ab07d0000000 */ ++ 1.38390988111495971680e+00, /* 0x3ff6247eb0000000 */ ++ 1.41421353816986083984e+00, /* 0x3ff6a09e60000000 */ ++ 1.44518077373504638672e+00, /* 0x3ff71f75e0000000 */ ++ 1.47682613134384155273e+00, /* 0x3ff7a11470000000 */ ++ 1.50916439294815063477e+00, /* 0x3ff8258990000000 */ ++ 1.54221081733703613281e+00, /* 0x3ff8ace540000000 */ ++ 1.57598084211349487305e+00, /* 0x3ff93737b0000000 */ ++ 1.61049032211303710938e+00, /* 0x3ff9c49180000000 */ ++ 1.64575546979904174805e+00, /* 0x3ffa5503b0000000 */ ++ 1.68179279565811157227e+00, /* 0x3ffae89f90000000 */ ++ 1.71861928701400756836e+00, /* 0x3ffb7f76f0000000 */ ++ 1.75625211000442504883e+00, /* 0x3ffc199bd0000000 */ ++ 1.79470902681350708008e+00, /* 0x3ffcb720d0000000 */ ++ 1.83400803804397583008e+00, /* 0x3ffd5818d0000000 */ ++ 1.87416762113571166992e+00, /* 0x3ffdfc9730000000 */ ++ 1.91520655155181884766e+00, /* 0x3ffea4afa0000000 */ ++ 1.95714408159255981445e+00}; /* 0x3fff507650000000 */ ++ ++ static const double two_to_jby32_trail_table[32] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.14890470981563546737e-08, /* 0x3e48ac2ba1d73e2a */ ++ 4.83347014379782142328e-08, /* 0x3e69f3121ec53172 */ ++ 2.67125131841396124714e-10, /* 0x3df25b50a4ebbf1b */ ++ 4.65271045830351350190e-08, /* 0x3e68faa2f5b9bef9 */ ++ 5.24924336638693782574e-09, /* 0x3e368b9aa7805b80 */ ++ 5.38622214388600821910e-08, /* 0x3e6ceac470cd83f6 */ ++ 1.90902301017041969782e-08, /* 0x3e547f7b84b09745 */ ++ 3.79763538792174980894e-08, /* 0x3e64636e2a5bd1ab */ ++ 2.69306947081946450986e-08, /* 0x3e5ceaa72a9c5154 */ ++ 4.49683815095311756138e-08, /* 0x3e682468446b6824 */ ++ 1.41933332021066904914e-09, /* 0x3e18624b40c4dbd0 */ ++ 1.94146510233556266402e-08, /* 0x3e54d8a89c750e5e */ ++ 2.46409119489264118569e-08, /* 0x3e5a753e077c2a0f */ ++ 4.94812958044698886494e-08, /* 0x3e6a90a852b19260 */ ++ 8.48872238075784476136e-10, /* 0x3e0d2ac258f87d03 */ ++ 2.42032342089579394887e-08, /* 0x3e59fcef32422cbf */ ++ 3.32420002333182569170e-08, /* 0x3e61d8bee7ba46e2 */ ++ 1.45956577586525322754e-08, /* 0x3e4f580c36bea881 */ ++ 3.46452721050003920866e-08, /* 0x3e62999c25159f11 */ ++ 8.07090469079979051284e-09, /* 0x3e415506dadd3e2a */ ++ 2.99439161340839520436e-09, /* 0x3e29b8bc9e8a0388 */ ++ 9.83621719880452147153e-09, /* 0x3e451f8480e3e236 */ ++ 8.35492309647188080486e-09, /* 0x3e41f12ae45a1224 */ ++ 3.48493175137966283582e-08, /* 0x3e62b5a75abd0e6a */ ++ 1.11084703472699692902e-08, /* 0x3e47daf237553d84 */ ++ 5.03688744342840346564e-08, /* 0x3e6b0aa538444196 */ ++ 4.81896001063495806249e-08, /* 0x3e69df20d22a0798 */ ++ 4.83653666334089557746e-08, /* 0x3e69f7490e4bb40b */ ++ 1.29745882314081237628e-08, /* 0x3e4bdcdaf5cb4656 */ ++ 9.84532844621636118964e-09, /* 0x3e452486cc2c7b9d */ ++ 4.25828404545651943883e-08}; /* 0x3e66dc8a80ce9f09 */ ++ ++ /* ++ Step 1. Reduce the argument. ++ ++ To perform argument reduction, we find the integer n such that ++ x = n * logbaseof2/32 + remainder, |remainder| <= logbaseof2/64. ++ n is defined by round-to-nearest-integer( x*32/logbaseof2 ) and ++ remainder by x - n*logbaseof2/32. The calculation of n is ++ straightforward whereas the computation of x - n*logbaseof2/32 ++ must be carried out carefully. ++ logbaseof2/32 is so represented in two pieces that ++ (1) logbaseof2/32 is known to extra precision, (2) the product ++ of n and the leading piece is a model number and is hence ++ calculated without error, and (3) the subtraction of the value ++ obtained in (2) from x is a model number and is hence again ++ obtained without error. ++ */ ++ ++ r = x * thirtytwo_by_logbaseof2; ++ /* Set n = nearest integer to r */ ++ /* This is faster on Hammer */ ++ if (r > 0) ++ n = (int)(r + 0.5); ++ else ++ n = (int)(r - 0.5); ++ ++ r1 = x - n * logbaseof2_by_32_lead; ++ r2 = - n * logbaseof2_by_32_trail; ++ ++ /* Set j = n mod 32: 5 mod 32 = 5, -5 mod 32 = 27, etc. */ ++ /* j = n % 32; ++ if (j < 0) j += 32; */ ++ j = n & 0x0000001f; ++ ++ f1 = two_to_jby32_lead_table[j]; ++ f2 = two_to_jby32_trail_table[j]; ++ ++ *m = (n - j) / 32; ++ ++ /* Step 2. The following is the core approximation. We approximate ++ exp(r1+r2)-1 by a polynomial. */ ++ ++ r1 *= logbase; r2 *= logbase; ++ ++ r = r1 + r2; ++ q = r1 + (r2 + ++ r*r*( 5.00000000000000008883e-01 + ++ r*( 1.66666666665260878863e-01 + ++ r*( 4.16666666662260795726e-02 + ++ r*( 8.33336798434219616221e-03 + ++ r*( 1.38889490863777199667e-03 )))))); ++ ++ /* Step 3. Function value reconstruction. ++ We now reconstruct the exponential of the input argument ++ so that exp(x) = 2**m * (z1 + z2). ++ The order of the computation below must be strictly observed. */ ++ ++ *z1 = f1; ++ *z2 = f2 + ((f1 + f2) * q); ++} ++#endif /* USE_SPLITEXP */ ++ ++ ++#if defined(USE_SPLITEXPF) ++/* Compute the values m, z1, and z2 such that base**x = 2**m * (z1 + z2). ++ Small arguments abs(x) < 1/(16*ln(base)) and extreme arguments ++ abs(x) > large/(ln(base)) (where large is the largest representable ++ floating point number) should be handled separately instead of calling ++ this function. This function is called by exp_amd, exp2_amd, exp10_amd, ++ cosh_amd and sinh_amd. */ ++static inline void splitexpf(float x, float logbase, ++ float thirtytwo_by_logbaseof2, ++ float logbaseof2_by_32_lead, ++ float logbaseof2_by_32_trail, ++ int *m, float *z1, float *z2) ++{ ++ float q, r, r1, r2, f1, f2; ++ int n, j; ++ ++/* Arrays two_to_jby32_lead_table and two_to_jby32_trail_table contain ++ leading and trailing parts respectively of precomputed ++ values of pow(2.0,j/32.0), for j = 0, 1, ..., 31. ++ two_to_jby32_lead_table contains the first 10 bits of precision, ++ and two_to_jby32_trail_table contains a further 24 bits precision. */ ++ ++ static const float two_to_jby32_lead_table[32] = { ++ 1.0000000000E+00F, /* 0x3F800000 */ ++ 1.0214843750E+00F, /* 0x3F82C000 */ ++ 1.0429687500E+00F, /* 0x3F858000 */ ++ 1.0664062500E+00F, /* 0x3F888000 */ ++ 1.0898437500E+00F, /* 0x3F8B8000 */ ++ 1.1132812500E+00F, /* 0x3F8E8000 */ ++ 1.1386718750E+00F, /* 0x3F91C000 */ ++ 1.1621093750E+00F, /* 0x3F94C000 */ ++ 1.1875000000E+00F, /* 0x3F980000 */ ++ 1.2148437500E+00F, /* 0x3F9B8000 */ ++ 1.2402343750E+00F, /* 0x3F9EC000 */ ++ 1.2675781250E+00F, /* 0x3FA24000 */ ++ 1.2949218750E+00F, /* 0x3FA5C000 */ ++ 1.3242187500E+00F, /* 0x3FA98000 */ ++ 1.3535156250E+00F, /* 0x3FAD4000 */ ++ 1.3828125000E+00F, /* 0x3FB10000 */ ++ 1.4140625000E+00F, /* 0x3FB50000 */ ++ 1.4433593750E+00F, /* 0x3FB8C000 */ ++ 1.4765625000E+00F, /* 0x3FBD0000 */ ++ 1.5078125000E+00F, /* 0x3FC10000 */ ++ 1.5410156250E+00F, /* 0x3FC54000 */ ++ 1.5742187500E+00F, /* 0x3FC98000 */ ++ 1.6093750000E+00F, /* 0x3FCE0000 */ ++ 1.6445312500E+00F, /* 0x3FD28000 */ ++ 1.6816406250E+00F, /* 0x3FD74000 */ ++ 1.7167968750E+00F, /* 0x3FDBC000 */ ++ 1.7558593750E+00F, /* 0x3FE0C000 */ ++ 1.7929687500E+00F, /* 0x3FE58000 */ ++ 1.8339843750E+00F, /* 0x3FEAC000 */ ++ 1.8730468750E+00F, /* 0x3FEFC000 */ ++ 1.9140625000E+00F, /* 0x3FF50000 */ ++ 1.9570312500E+00F}; /* 0x3FFA8000 */ ++ ++ static const float two_to_jby32_trail_table[32] = { ++ 0.0000000000E+00F, /* 0x00000000 */ ++ 4.1277357377E-04F, /* 0x39D86988 */ ++ 1.3050324051E-03F, /* 0x3AAB0D9F */ ++ 7.3415064253E-04F, /* 0x3A407404 */ ++ 6.6398258787E-04F, /* 0x3A2E0F1E */ ++ 1.1054925853E-03F, /* 0x3A90E62D */ ++ 1.1675967835E-04F, /* 0x38F4DCE0 */ ++ 1.6154836630E-03F, /* 0x3AD3BEA3 */ ++ 1.7071149778E-03F, /* 0x3ADFC146 */ ++ 4.0360994171E-04F, /* 0x39D39B9C */ ++ 1.6234370414E-03F, /* 0x3AD4C982 */ ++ 1.4728321694E-03F, /* 0x3AC10C0C */ ++ 1.9176795613E-03F, /* 0x3AFB5AA6 */ ++ 1.0178930825E-03F, /* 0x3A856AD3 */ ++ 7.3992193211E-04F, /* 0x3A41F752 */ ++ 1.0973819299E-03F, /* 0x3A8FD607 */ ++ 1.5106226783E-04F, /* 0x391E6678 */ ++ 1.8214319134E-03F, /* 0x3AEEBD1D */ ++ 2.6364589576E-04F, /* 0x398A39F4 */ ++ 1.3519275235E-03F, /* 0x3AB13329 */ ++ 1.1952003697E-03F, /* 0x3A9CA845 */ ++ 1.7620950239E-03F, /* 0x3AE6F619 */ ++ 1.1153318919E-03F, /* 0x3A923054 */ ++ 1.2242280645E-03F, /* 0x3AA07647 */ ++ 1.5220546629E-04F, /* 0x391F9958 */ ++ 1.8224230735E-03F, /* 0x3AEEDE5F */ ++ 3.9278529584E-04F, /* 0x39CDEEC0 */ ++ 1.7403248930E-03F, /* 0x3AE41B9D */ ++ 2.3711356334E-05F, /* 0x37C6E7C0 */ ++ 1.1207590578E-03F, /* 0x3A92E66F */ ++ 1.1440613307E-03F, /* 0x3A95F454 */ ++ 1.1287408415E-04F}; /* 0x38ECB6D0 */ ++ ++ /* ++ Step 1. Reduce the argument. ++ ++ To perform argument reduction, we find the integer n such that ++ x = n * logbaseof2/32 + remainder, |remainder| <= logbaseof2/64. ++ n is defined by round-to-nearest-integer( x*32/logbaseof2 ) and ++ remainder by x - n*logbaseof2/32. The calculation of n is ++ straightforward whereas the computation of x - n*logbaseof2/32 ++ must be carried out carefully. ++ logbaseof2/32 is so represented in two pieces that ++ (1) logbaseof2/32 is known to extra precision, (2) the product ++ of n and the leading piece is a model number and is hence ++ calculated without error, and (3) the subtraction of the value ++ obtained in (2) from x is a model number and is hence again ++ obtained without error. ++ */ ++ ++ r = x * thirtytwo_by_logbaseof2; ++ /* Set n = nearest integer to r */ ++ /* This is faster on Hammer */ ++ if (r > 0) ++ n = (int)(r + 0.5F); ++ else ++ n = (int)(r - 0.5F); ++ ++ r1 = x - n * logbaseof2_by_32_lead; ++ r2 = - n * logbaseof2_by_32_trail; ++ ++ /* Set j = n mod 32: 5 mod 32 = 5, -5 mod 32 = 27, etc. */ ++ /* j = n % 32; ++ if (j < 0) j += 32; */ ++ j = n & 0x0000001f; ++ ++ f1 = two_to_jby32_lead_table[j]; ++ f2 = two_to_jby32_trail_table[j]; ++ ++ *m = (n - j) / 32; ++ ++ /* Step 2. The following is the core approximation. We approximate ++ exp(r1+r2)-1 by a polynomial. */ ++ ++ r1 *= logbase; r2 *= logbase; ++ ++ r = r1 + r2; ++ q = r1 + (r2 + ++ r*r*( 5.00000000000000008883e-01F + ++ r*( 1.66666666665260878863e-01F ))); ++ ++ /* Step 3. Function value reconstruction. ++ We now reconstruct the exponential of the input argument ++ so that exp(x) = 2**m * (z1 + z2). ++ The order of the computation below must be strictly observed. */ ++ ++ *z1 = f1; ++ *z2 = f2 + ((f1 + f2) * q); ++} ++#endif /* SPLITEXPF */ ++ ++ ++#if defined(USE_SCALEUPDOUBLE1024) ++/* Scales up a double (normal or denormal) whose bit pattern is given ++ as ux by 2**1024. There are no checks that the input number is ++ scalable by that amount. */ ++static inline void scaleUpDouble1024(unsigned long ux, unsigned long *ur) ++{ ++ unsigned long uy; ++ double y; ++ ++ if ((ux & EXPBITS_DP64) == 0) ++ { ++ /* ux is denormalised */ ++ PUT_BITS_DP64(ux | 0x4010000000000000, y); ++ if (ux & SIGNBIT_DP64) ++ y += 4.0; ++ else ++ y -= 4.0; ++ GET_BITS_DP64(y, uy); ++ } ++ else ++ /* ux is normal */ ++ uy = ux + 0x4000000000000000; ++ ++ *ur = uy; ++ return; ++} ++ ++#endif /* SCALEUPDOUBLE1024 */ ++ ++ ++#if defined(USE_SCALEDOWNDOUBLE) ++/* Scales down a double whose bit pattern is given as ux by 2**k. ++ There are no checks that the input number is scalable by that amount. */ ++static inline void scaleDownDouble(unsigned long ux, int k, ++ unsigned long *ur) ++{ ++ unsigned long uy, uk, ax, xsign; ++ int n, shift; ++ xsign = ux & SIGNBIT_DP64; ++ ax = ux & ~SIGNBIT_DP64; ++ n = ((ax & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - k; ++ if (n > 0) ++ { ++ uk = (unsigned long)n << EXPSHIFTBITS_DP64; ++ uy = (ax & ~EXPBITS_DP64) | uk; ++ } ++ else ++ { ++ uy = (ax & ~EXPBITS_DP64) | 0x0010000000000000; ++ shift = (1 - n); ++ if (shift > MANTLENGTH_DP64 + 1) ++ /* Sigh. Shifting works mod 64 so be careful not to shift too much */ ++ uy = 0; ++ else ++ { ++ /* Make sure we round the result */ ++ uy >>= shift - 1; ++ uy = (uy >> 1) + (uy & 1); ++ } ++ } ++ *ur = uy | xsign; ++} ++ ++#endif /* SCALEDOWNDOUBLE */ ++ ++ ++#if defined(USE_SCALEUPFLOAT128) ++/* Scales up a float (normal or denormal) whose bit pattern is given ++ as ux by 2**128. There are no checks that the input number is ++ scalable by that amount. */ ++static inline void scaleUpFloat128(unsigned int ux, unsigned int *ur) ++{ ++ unsigned int uy; ++ float y; ++ ++ if ((ux & EXPBITS_SP32) == 0) ++ { ++ /* ux is denormalised */ ++ PUT_BITS_SP32(ux | 0x40800000, y); ++ /* Compensate for the implicit bit just added */ ++ if (ux & SIGNBIT_SP32) ++ y += 4.0F; ++ else ++ y -= 4.0F; ++ GET_BITS_SP32(y, uy); ++ } ++ else ++ /* ux is normal */ ++ uy = ux + 0x40000000; ++ *ur = uy; ++} ++#endif /* SCALEUPFLOAT128 */ ++ ++ ++#if defined(USE_SCALEDOWNFLOAT) ++/* Scales down a float whose bit pattern is given as ux by 2**k. ++ There are no checks that the input number is scalable by that amount. */ ++static inline void scaleDownFloat(unsigned int ux, int k, ++ unsigned int *ur) ++{ ++ unsigned int uy, uk, ax, xsign; ++ int n, shift; ++ ++ xsign = ux & SIGNBIT_SP32; ++ ax = ux & ~SIGNBIT_SP32; ++ n = ((ax & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - k; ++ if (n > 0) ++ { ++ uk = (unsigned int)n << EXPSHIFTBITS_SP32; ++ uy = (ax & ~EXPBITS_SP32) | uk; ++ } ++ else ++ { ++ uy = (ax & ~EXPBITS_SP32) | 0x00800000; ++ shift = (1 - n); ++ if (shift > MANTLENGTH_SP32 + 1) ++ /* Sigh. Shifting works mod 32 so be careful not to shift too much */ ++ uy = 0; ++ else ++ { ++ /* Make sure we round the result */ ++ uy >>= shift - 1; ++ uy = (uy >> 1) + (uy & 1); ++ } ++ } ++ *ur = uy | xsign; ++} ++#endif /* SCALEDOWNFLOAT */ ++ ++ ++#if defined(USE_SQRT_AMD_INLINE) ++static inline double sqrt_amd_inline(double x) ++{ ++ /* ++ Computes the square root of x. ++ ++ The calculation is carried out in three steps. ++ ++ Step 1. Reduction. ++ The input argument is scaled to the interval [1, 4) by ++ computing ++ x = 2^e * y, where y in [1,4). ++ Furthermore y is decomposed as y = c + t where ++ c = 1 + j/32, j = 0,1,..,96; and |t| <= 1/64. ++ ++ Step 2. Approximation. ++ An approximation q = sqrt(1 + (t/c)) - 1 is obtained ++ from a basic series expansion using precomputed values ++ stored in rt_jby32_lead_table_dbl and rt_jby32_trail_table_dbl. ++ ++ Step 3. Reconstruction. ++ The value of sqrt(x) is reconstructed via ++ sqrt(x) = 2^(e/2) * sqrt(y) ++ = 2^(e/2) * sqrt(c) * sqrt(y/c) ++ = 2^(e/2) * sqrt(c) * sqrt(1 + t/c) ++ = 2^(e/2) * [ sqrt(c) + sqrt(c)*q ] ++ */ ++ ++ unsigned long ux, ax, u; ++ double r1, r2, c, y, p, q, r, twop, z, rtc, rtc_lead, rtc_trail; ++ int e, denorm = 0, index; ++ ++/* Arrays rt_jby32_lead_table_dbl and rt_jby32_trail_table_dbl contain ++ leading and trailing parts respectively of precomputed ++ values of sqrt(j/32), for j = 32, 33, ..., 128. ++ rt_jby32_lead_table_dbl contains the first 21 bits of precision, ++ and rt_jby32_trail_table_dbl contains a further 53 bits precision. */ ++ ++ static const double rt_jby32_lead_table_dbl[97] = { ++ 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ ++ 1.01550388336181640625e+00, /* 0x3ff03f8100000000 */ ++ 1.03077602386474609375e+00, /* 0x3ff07e0f00000000 */ ++ 1.04582500457763671875e+00, /* 0x3ff0bbb300000000 */ ++ 1.06065940856933593750e+00, /* 0x3ff0f87600000000 */ ++ 1.07528972625732421875e+00, /* 0x3ff1346300000000 */ ++ 1.08972454071044921875e+00, /* 0x3ff16f8300000000 */ ++ 1.10396957397460937500e+00, /* 0x3ff1a9dc00000000 */ ++ 1.11803340911865234375e+00, /* 0x3ff1e37700000000 */ ++ 1.13192272186279296875e+00, /* 0x3ff21c5b00000000 */ ++ 1.14564323425292968750e+00, /* 0x3ff2548e00000000 */ ++ 1.15920162200927734375e+00, /* 0x3ff28c1700000000 */ ++ 1.17260360717773437500e+00, /* 0x3ff2c2fc00000000 */ ++ 1.18585395812988281250e+00, /* 0x3ff2f94200000000 */ ++ 1.19895744323730468750e+00, /* 0x3ff32eee00000000 */ ++ 1.21191978454589843750e+00, /* 0x3ff3640600000000 */ ++ 1.22474479675292968750e+00, /* 0x3ff3988e00000000 */ ++ 1.23743629455566406250e+00, /* 0x3ff3cc8a00000000 */ ++ 1.25000000000000000000e+00, /* 0x3ff4000000000000 */ ++ 1.26243782043457031250e+00, /* 0x3ff432f200000000 */ ++ 1.27475452423095703125e+00, /* 0x3ff4656500000000 */ ++ 1.28695297241210937500e+00, /* 0x3ff4975c00000000 */ ++ 1.29903793334960937500e+00, /* 0x3ff4c8dc00000000 */ ++ 1.31101036071777343750e+00, /* 0x3ff4f9e600000000 */ ++ 1.32287502288818359375e+00, /* 0x3ff52a7f00000000 */ ++ 1.33463478088378906250e+00, /* 0x3ff55aaa00000000 */ ++ 1.34629058837890625000e+00, /* 0x3ff58a6800000000 */ ++ 1.35784721374511718750e+00, /* 0x3ff5b9be00000000 */ ++ 1.36930561065673828125e+00, /* 0x3ff5e8ad00000000 */ ++ 1.38066959381103515625e+00, /* 0x3ff6173900000000 */ ++ 1.39194107055664062500e+00, /* 0x3ff6456400000000 */ ++ 1.40312099456787109375e+00, /* 0x3ff6732f00000000 */ ++ 1.41421318054199218750e+00, /* 0x3ff6a09e00000000 */ ++ 1.42521858215332031250e+00, /* 0x3ff6cdb200000000 */ ++ 1.43614006042480468750e+00, /* 0x3ff6fa6e00000000 */ ++ 1.44697952270507812500e+00, /* 0x3ff726d400000000 */ ++ 1.45773792266845703125e+00, /* 0x3ff752e500000000 */ ++ 1.46841716766357421875e+00, /* 0x3ff77ea300000000 */ ++ 1.47901916503906250000e+00, /* 0x3ff7aa1000000000 */ ++ 1.48954677581787109375e+00, /* 0x3ff7d52f00000000 */ ++ 1.50000000000000000000e+00, /* 0x3ff8000000000000 */ ++ 1.51038074493408203125e+00, /* 0x3ff82a8500000000 */ ++ 1.52068996429443359375e+00, /* 0x3ff854bf00000000 */ ++ 1.53093051910400390625e+00, /* 0x3ff87eb100000000 */ ++ 1.54110336303710937500e+00, /* 0x3ff8a85c00000000 */ ++ 1.55120849609375000000e+00, /* 0x3ff8d1c000000000 */ ++ 1.56124877929687500000e+00, /* 0x3ff8fae000000000 */ ++ 1.57122516632080078125e+00, /* 0x3ff923bd00000000 */ ++ 1.58113861083984375000e+00, /* 0x3ff94c5800000000 */ ++ 1.59099006652832031250e+00, /* 0x3ff974b200000000 */ ++ 1.60078048706054687500e+00, /* 0x3ff99ccc00000000 */ ++ 1.61051177978515625000e+00, /* 0x3ff9c4a800000000 */ ++ 1.62018489837646484375e+00, /* 0x3ff9ec4700000000 */ ++ 1.62979984283447265625e+00, /* 0x3ffa13a900000000 */ ++ 1.63935947418212890625e+00, /* 0x3ffa3ad100000000 */ ++ 1.64886283874511718750e+00, /* 0x3ffa61be00000000 */ ++ 1.65831184387207031250e+00, /* 0x3ffa887200000000 */ ++ 1.66770744323730468750e+00, /* 0x3ffaaeee00000000 */ ++ 1.67705059051513671875e+00, /* 0x3ffad53300000000 */ ++ 1.68634128570556640625e+00, /* 0x3ffafb4100000000 */ ++ 1.69558238983154296875e+00, /* 0x3ffb211b00000000 */ ++ 1.70477199554443359375e+00, /* 0x3ffb46bf00000000 */ ++ 1.71391296386718750000e+00, /* 0x3ffb6c3000000000 */ ++ 1.72300529479980468750e+00, /* 0x3ffb916e00000000 */ ++ 1.73204994201660156250e+00, /* 0x3ffbb67a00000000 */ ++ 1.74104785919189453125e+00, /* 0x3ffbdb5500000000 */ ++ 1.75000000000000000000e+00, /* 0x3ffc000000000000 */ ++ 1.75890541076660156250e+00, /* 0x3ffc247a00000000 */ ++ 1.76776695251464843750e+00, /* 0x3ffc48c600000000 */ ++ 1.77658367156982421875e+00, /* 0x3ffc6ce300000000 */ ++ 1.78535652160644531250e+00, /* 0x3ffc90d200000000 */ ++ 1.79408740997314453125e+00, /* 0x3ffcb49500000000 */ ++ 1.80277538299560546875e+00, /* 0x3ffcd82b00000000 */ ++ 1.81142139434814453125e+00, /* 0x3ffcfb9500000000 */ ++ 1.82002735137939453125e+00, /* 0x3ffd1ed500000000 */ ++ 1.82859230041503906250e+00, /* 0x3ffd41ea00000000 */ ++ 1.83711719512939453125e+00, /* 0x3ffd64d500000000 */ ++ 1.84560203552246093750e+00, /* 0x3ffd879600000000 */ ++ 1.85404872894287109375e+00, /* 0x3ffdaa2f00000000 */ ++ 1.86245727539062500000e+00, /* 0x3ffdcca000000000 */ ++ 1.87082862854003906250e+00, /* 0x3ffdeeea00000000 */ ++ 1.87916183471679687500e+00, /* 0x3ffe110c00000000 */ ++ 1.88745784759521484375e+00, /* 0x3ffe330700000000 */ ++ 1.89571857452392578125e+00, /* 0x3ffe54dd00000000 */ ++ 1.90394306182861328125e+00, /* 0x3ffe768d00000000 */ ++ 1.91213226318359375000e+00, /* 0x3ffe981800000000 */ ++ 1.92028617858886718750e+00, /* 0x3ffeb97e00000000 */ ++ 1.92840576171875000000e+00, /* 0x3ffedac000000000 */ ++ 1.93649101257324218750e+00, /* 0x3ffefbde00000000 */ ++ 1.94454288482666015625e+00, /* 0x3fff1cd900000000 */ ++ 1.95256233215332031250e+00, /* 0x3fff3db200000000 */ ++ 1.96054744720458984375e+00, /* 0x3fff5e6700000000 */ ++ 1.96850109100341796875e+00, /* 0x3fff7efb00000000 */ ++ 1.97642326354980468750e+00, /* 0x3fff9f6e00000000 */ ++ 1.98431301116943359375e+00, /* 0x3fffbfbf00000000 */ ++ 1.99217128753662109375e+00, /* 0x3fffdfef00000000 */ ++ 2.00000000000000000000e+00}; /* 0x4000000000000000 */ ++ ++ static const double rt_jby32_trail_table_dbl[97] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 9.17217678638807524014e-07, /* 0x3eaec6d70177881c */ ++ 3.82539669043705364790e-07, /* 0x3e99abfb41bd6b24 */ ++ 2.85899577162227138140e-08, /* 0x3e5eb2bf6bab55a2 */ ++ 7.63210485349101216659e-07, /* 0x3ea99bed9b2d8d0c */ ++ 9.32123004127716212874e-07, /* 0x3eaf46e029c1b296 */ ++ 1.95174719169309219157e-07, /* 0x3e8a3226fc42f30c */ ++ 5.34316371481845492427e-07, /* 0x3ea1edbe20701d73 */ ++ 5.79631242504454563052e-07, /* 0x3ea372fe94f82be7 */ ++ 4.20404384109571705948e-07, /* 0x3e9c367e08e7bb06 */ ++ 6.89486030314147010716e-07, /* 0x3ea722a3d0a66608 */ ++ 6.89927685625314560328e-07, /* 0x3ea7266f067ca1d6 */ ++ 3.32778123013641425828e-07, /* 0x3e965515a9b34850 */ ++ 1.64433259436999584387e-07, /* 0x3e8611e23ef6c1bd */ ++ 4.37590875197899335723e-07, /* 0x3e9d5dc1059ed8e7 */ ++ 1.79808183816018617413e-07, /* 0x3e88222982d0e4f4 */ ++ 7.46386593615986477624e-08, /* 0x3e7409212e7d0322 */ ++ 5.72520794105201454728e-07, /* 0x3ea335ea8a5fcf39 */ ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 2.96860689431670420344e-07, /* 0x3e93ec071e938bfe */ ++ 3.54167239176257065345e-07, /* 0x3e97c48bfd9862c6 */ ++ 7.95211265664474710063e-07, /* 0x3eaaaed010f74671 */ ++ 1.72327048595145565621e-07, /* 0x3e87211cbfeb62e0 */ ++ 6.99494915996239297020e-07, /* 0x3ea7789d9660e72d */ ++ 6.32644111701500844315e-07, /* 0x3ea53a5f1d36f1cf */ ++ 6.20124838851440463844e-10, /* 0x3e054eacff2057dc */ ++ 6.13404719757812629969e-07, /* 0x3ea4951b3e6a83cc */ ++ 3.47654909777986407387e-07, /* 0x3e9754aa76884c66 */ ++ 7.83106177002392475763e-07, /* 0x3eaa46d4b1de1074 */ ++ 5.33337372440526357008e-07, /* 0x3ea1e55548f92635 */ ++ 2.01508648555298681765e-08, /* 0x3e55a3070dd17788 */ ++ 5.25472356925843939587e-07, /* 0x3ea1a1c5eedb0801 */ ++ 3.81831102861301692797e-07, /* 0x3e999fcef32422cc */ ++ 6.99220602161420018738e-07, /* 0x3ea776425d6b0199 */ ++ 6.01209702477462624811e-07, /* 0x3ea42c5a1e0191a2 */ ++ 9.01437000591944740554e-08, /* 0x3e7832a0bdff1327 */ ++ 5.10428680864685379950e-08, /* 0x3e6b674743636676 */ ++ 3.47895267104621031421e-07, /* 0x3e9758cb90d2f714 */ ++ 7.80735841510641848628e-07, /* 0x3eaa3278459cde25 */ ++ 1.35158752025506517690e-07, /* 0x3e822404f4a103ee */ ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.76523947728535489812e-09, /* 0x3e1e539af6892ac5 */ ++ 6.68280121328499932183e-07, /* 0x3ea66c7b872c9cd0 */ ++ 5.70135482405123276616e-07, /* 0x3ea3216d2f43887d */ ++ 1.37705134737562525897e-07, /* 0x3e827b832cbedc0e */ ++ 7.09655107074516613672e-07, /* 0x3ea7cfe41579091d */ ++ 7.20302724551461693011e-07, /* 0x3ea82b5a713c490a */ ++ 4.69926266058212796694e-07, /* 0x3e9f8945932d872e */ ++ 2.19244345915999437026e-07, /* 0x3e8d6d2da9490251 */ ++ 1.91141411617401877927e-07, /* 0x3e89a791a3114e4a */ ++ 5.72297665296622053774e-07, /* 0x3ea333ffe005988d */ ++ 5.61055484436830560103e-07, /* 0x3ea2d36e0ed49ab1 */ ++ 2.76225500213991506100e-07, /* 0x3e92898498f55f9e */ ++ 7.58466189522395692908e-07, /* 0x3ea9732cca1032a3 */ ++ 1.56893371256836029827e-07, /* 0x3e850ed0b02a22d2 */ ++ 4.06038997708867066507e-07, /* 0x3e9b3fb265b1e40a */ ++ 5.51305629612057435809e-07, /* 0x3ea27fade682d1de */ ++ 5.64778487026561123207e-07, /* 0x3ea2f36906f707ba */ ++ 3.92609705553556897517e-07, /* 0x3e9a58fbbee883b6 */ ++ 9.09698438776943827802e-07, /* 0x3eae864005bca6d7 */ ++ 1.05949774066016139743e-07, /* 0x3e7c70d02300f263 */ ++ 7.16578798392844784244e-07, /* 0x3ea80b5d712d8e3e */ ++ 6.86233073531233972561e-07, /* 0x3ea706b27cc7d390 */ ++ 7.99211473033494452908e-07, /* 0x3eaad12c9d849a97 */ ++ 8.65552275731027456121e-07, /* 0x3ead0b09954e764b */ ++ 6.75456120386058448618e-07, /* 0x3ea6aa1fb7826cbd */ ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 4.99167184520462138743e-07, /* 0x3ea0bfd03f46763c */ ++ 4.51720373502110930296e-10, /* 0x3dff0abfb4adfb9e */ ++ 1.28874162718371367439e-07, /* 0x3e814c151f991b2e */ ++ 5.85529267186999798656e-07, /* 0x3ea3a5a879b09292 */ ++ 1.01827770937125531924e-07, /* 0x3e7b558d173f9796 */ ++ 2.54736389177809626508e-07, /* 0x3e9118567cd83fb8 */ ++ 6.98925535290464831294e-07, /* 0x3ea773b981896751 */ ++ 1.20940735036524314513e-07, /* 0x3e803b7df49f48a8 */ ++ 5.43759351196479689657e-08, /* 0x3e6d315f22491900 */ ++ 1.11957989042397958409e-07, /* 0x3e7e0db1c5bb84b2 */ ++ 8.47006714134442661218e-07, /* 0x3eac6bbb7644ff76 */ ++ 8.92831044643427836228e-07, /* 0x3eadf55c3afec01f */ ++ 7.77828292464916501663e-07, /* 0x3eaa197e81034da3 */ ++ 6.48469316302918797451e-08, /* 0x3e71683f4920555d */ ++ 2.12579816658859849140e-07, /* 0x3e8c882fd78bb0b0 */ ++ 7.61222472580559138435e-07, /* 0x3ea98ad9eb7b83ec */ ++ 2.86488961857314189607e-07, /* 0x3e9339d7c7777273 */ ++ 2.14637363790165363515e-07, /* 0x3e8ccee237cae6fe */ ++ 5.44137005612605847831e-08, /* 0x3e6d368fe324a146 */ ++ 2.58378284856442408413e-07, /* 0x3e9156e7b6d99b45 */ ++ 3.15848939061134843091e-07, /* 0x3e95323e5310b5c1 */ ++ 6.60530466255089632309e-07, /* 0x3ea629e9db362f5d */ ++ 7.63436345535852301127e-07, /* 0x3ea99dde4728d7ec */ ++ 8.68233432860324345268e-08, /* 0x3e774e746878544d */ ++ 9.45465175398023087082e-07, /* 0x3eafb97be873a87d */ ++ 8.77499534786171267246e-07, /* 0x3ead71a9e23c2f63 */ ++ 2.74055432394999316135e-07, /* 0x3e92643c89cda173 */ ++ 4.72129009349126213532e-07, /* 0x3e9faf1d57a4d56c */ ++ 8.93777032327078947306e-07, /* 0x3eadfd7c7ab7b282 */ ++ 0.00000000000000000000e+00}; /* 0x0000000000000000 */ ++ ++ ++ /* Handle special arguments first */ ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ if(ax >= 0x7ff0000000000000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_DP64) ++ /* x is negative infinity */ ++ return nan_with_flags(AMD_F_INVALID); ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ else if (ux & SIGNBIT_DP64) ++ { ++ /* x is negative. */ ++ if (ux == SIGNBIT_DP64) ++ /* Handle negative zero first */ ++ return x; ++ else ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ else if (ux <= 0x000fffffffffffff) ++ { ++ /* x is denormalised or zero */ ++ if (ux == 0) ++ /* x is zero */ ++ return x; ++ else ++ { ++ /* x is denormalised; scale it up */ ++ /* Normalize x by increasing the exponent by 60 ++ and subtracting a correction to account for the implicit ++ bit. This replaces a slow denormalized ++ multiplication by a fast normal subtraction. */ ++ static const double corr = 2.5653355008114851558350183e-290; /* 0x03d0000000000000 */ ++ denorm = 1; ++ GET_BITS_DP64(x, ux); ++ PUT_BITS_DP64(ux | 0x03d0000000000000, x); ++ x -= corr; ++ GET_BITS_DP64(x, ux); ++ } ++ } ++ ++ /* Main algorithm */ ++ ++ /* ++ Find y and e such that x = 2^e * y, where y in [1,4). ++ This is done using an in-lined variant of splitDouble, ++ which also ensures that e is even. ++ */ ++ y = x; ++ ux &= EXPBITS_DP64; ++ ux >>= EXPSHIFTBITS_DP64; ++ if (ux & 1) ++ { ++ GET_BITS_DP64(y, u); ++ u &= (SIGNBIT_DP64 | MANTBITS_DP64); ++ u |= ONEEXPBITS_DP64; ++ PUT_BITS_DP64(u, y); ++ e = ux - EXPBIAS_DP64; ++ } ++ else ++ { ++ GET_BITS_DP64(y, u); ++ u &= (SIGNBIT_DP64 | MANTBITS_DP64); ++ u |= TWOEXPBITS_DP64; ++ PUT_BITS_DP64(u, y); ++ e = ux - EXPBIAS_DP64 - 1; ++ } ++ ++ ++ /* Find the index of the sub-interval of [1,4) in which y lies. */ ++ ++ index = (int)(32.0*y+0.5); ++ ++ /* Look up the table values and compute c and r = c/t */ ++ ++ rtc_lead = rt_jby32_lead_table_dbl[index-32]; ++ rtc_trail = rt_jby32_trail_table_dbl[index-32]; ++ c = 0.03125*index; ++ r = (y - c)/c; ++ ++ /* ++ Find q = sqrt(1+r) - 1. ++ From one step of Newton on (q+1)^2 = 1+r ++ */ ++ ++ p = r*0.5 - r*r*(0.1250079870 - r*(0.6250522999E-01)); ++ twop = p + p; ++ q = p - (p*p + (twop - r))/(twop + 2.0); ++ ++ /* Reconstruction */ ++ ++ rtc = rtc_lead + rtc_trail; ++ e >>= 1; /* e = e/2 */ ++ z = rtc_lead + (rtc*q+rtc_trail); ++ ++ if (denorm) ++ { ++ /* Scale by 2**(e-30) */ ++ PUT_BITS_DP64(((long)(e - 30) + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, r); ++ z *= r; ++ } ++ else ++ { ++ /* Scale by 2**e */ ++ PUT_BITS_DP64(((long)e + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, r); ++ z *= r; ++ } ++ ++ return z; ++ ++} ++#endif /* SQRT_AMD_INLINE */ ++ ++#if defined(USE_SQRTF_AMD_INLINE) ++ ++static inline float sqrtf_amd_inline(float x) ++{ ++ /* ++ Computes the square root of x. ++ ++ The calculation is carried out in three steps. ++ ++ Step 1. Reduction. ++ The input argument is scaled to the interval [1, 4) by ++ computing ++ x = 2^e * y, where y in [1,4). ++ Furthermore y is decomposed as y = c + t where ++ c = 1 + j/32, j = 0,1,..,96; and |t| <= 1/64. ++ ++ Step 2. Approximation. ++ An approximation q = sqrt(1 + (t/c)) - 1 is obtained ++ from a basic series expansion using precomputed values ++ stored in rt_jby32_lead_table_float and rt_jby32_trail_table_float. ++ ++ Step 3. Reconstruction. ++ The value of sqrt(x) is reconstructed via ++ sqrt(x) = 2^(e/2) * sqrt(y) ++ = 2^(e/2) * sqrt(c) * sqrt(y/c) ++ = 2^(e/2) * sqrt(c) * sqrt(1 + t/c) ++ = 2^(e/2) * [ sqrt(c) + sqrt(c)*q ] ++ */ ++ ++ unsigned int ux, ax, u; ++ float r1, r2, c, y, p, q, r, twop, z, rtc, rtc_lead, rtc_trail; ++ int e, denorm = 0, index; ++ ++/* Arrays rt_jby32_lead_table_float and rt_jby32_trail_table_float contain ++ leading and trailing parts respectively of precomputed ++ values of sqrt(j/32), for j = 32, 33, ..., 128. ++ rt_jby32_lead_table_float contains the first 13 bits of precision, ++ and rt_jby32_trail_table_float contains a further 24 bits precision. */ ++ ++static const float rt_jby32_lead_table_float[97] = { ++ 1.00000000000000000000e+00F, /* 0x3f800000 */ ++ 1.01538085937500000000e+00F, /* 0x3f81f800 */ ++ 1.03076171875000000000e+00F, /* 0x3f83f000 */ ++ 1.04565429687500000000e+00F, /* 0x3f85d800 */ ++ 1.06054687500000000000e+00F, /* 0x3f87c000 */ ++ 1.07519531250000000000e+00F, /* 0x3f89a000 */ ++ 1.08959960937500000000e+00F, /* 0x3f8b7800 */ ++ 1.10375976562500000000e+00F, /* 0x3f8d4800 */ ++ 1.11791992187500000000e+00F, /* 0x3f8f1800 */ ++ 1.13183593750000000000e+00F, /* 0x3f90e000 */ ++ 1.14550781250000000000e+00F, /* 0x3f92a000 */ ++ 1.15917968750000000000e+00F, /* 0x3f946000 */ ++ 1.17236328125000000000e+00F, /* 0x3f961000 */ ++ 1.18579101562500000000e+00F, /* 0x3f97c800 */ ++ 1.19873046875000000000e+00F, /* 0x3f997000 */ ++ 1.21191406250000000000e+00F, /* 0x3f9b2000 */ ++ 1.22460937500000000000e+00F, /* 0x3f9cc000 */ ++ 1.23730468750000000000e+00F, /* 0x3f9e6000 */ ++ 1.25000000000000000000e+00F, /* 0x3fa00000 */ ++ 1.26220703125000000000e+00F, /* 0x3fa19000 */ ++ 1.27465820312500000000e+00F, /* 0x3fa32800 */ ++ 1.28686523437500000000e+00F, /* 0x3fa4b800 */ ++ 1.29882812500000000000e+00F, /* 0x3fa64000 */ ++ 1.31079101562500000000e+00F, /* 0x3fa7c800 */ ++ 1.32275390625000000000e+00F, /* 0x3fa95000 */ ++ 1.33447265625000000000e+00F, /* 0x3faad000 */ ++ 1.34619140625000000000e+00F, /* 0x3fac5000 */ ++ 1.35766601562500000000e+00F, /* 0x3fadc800 */ ++ 1.36914062500000000000e+00F, /* 0x3faf4000 */ ++ 1.38061523437500000000e+00F, /* 0x3fb0b800 */ ++ 1.39184570312500000000e+00F, /* 0x3fb22800 */ ++ 1.40307617187500000000e+00F, /* 0x3fb39800 */ ++ 1.41406250000000000000e+00F, /* 0x3fb50000 */ ++ 1.42504882812500000000e+00F, /* 0x3fb66800 */ ++ 1.43603515625000000000e+00F, /* 0x3fb7d000 */ ++ 1.44677734375000000000e+00F, /* 0x3fb93000 */ ++ 1.45751953125000000000e+00F, /* 0x3fba9000 */ ++ 1.46826171875000000000e+00F, /* 0x3fbbf000 */ ++ 1.47900390625000000000e+00F, /* 0x3fbd5000 */ ++ 1.48950195312500000000e+00F, /* 0x3fbea800 */ ++ 1.50000000000000000000e+00F, /* 0x3fc00000 */ ++ 1.51025390625000000000e+00F, /* 0x3fc15000 */ ++ 1.52050781250000000000e+00F, /* 0x3fc2a000 */ ++ 1.53076171875000000000e+00F, /* 0x3fc3f000 */ ++ 1.54101562500000000000e+00F, /* 0x3fc54000 */ ++ 1.55102539062500000000e+00F, /* 0x3fc68800 */ ++ 1.56103515625000000000e+00F, /* 0x3fc7d000 */ ++ 1.57104492187500000000e+00F, /* 0x3fc91800 */ ++ 1.58105468750000000000e+00F, /* 0x3fca6000 */ ++ 1.59082031250000000000e+00F, /* 0x3fcba000 */ ++ 1.60058593750000000000e+00F, /* 0x3fcce000 */ ++ 1.61035156250000000000e+00F, /* 0x3fce2000 */ ++ 1.62011718750000000000e+00F, /* 0x3fcf6000 */ ++ 1.62963867187500000000e+00F, /* 0x3fd09800 */ ++ 1.63916015625000000000e+00F, /* 0x3fd1d000 */ ++ 1.64868164062500000000e+00F, /* 0x3fd30800 */ ++ 1.65820312500000000000e+00F, /* 0x3fd44000 */ ++ 1.66748046875000000000e+00F, /* 0x3fd57000 */ ++ 1.67700195312500000000e+00F, /* 0x3fd6a800 */ ++ 1.68627929687500000000e+00F, /* 0x3fd7d800 */ ++ 1.69555664062500000000e+00F, /* 0x3fd90800 */ ++ 1.70458984375000000000e+00F, /* 0x3fda3000 */ ++ 1.71386718750000000000e+00F, /* 0x3fdb6000 */ ++ 1.72290039062500000000e+00F, /* 0x3fdc8800 */ ++ 1.73193359375000000000e+00F, /* 0x3fddb000 */ ++ 1.74096679687500000000e+00F, /* 0x3fded800 */ ++ 1.75000000000000000000e+00F, /* 0x3fe00000 */ ++ 1.75878906250000000000e+00F, /* 0x3fe12000 */ ++ 1.76757812500000000000e+00F, /* 0x3fe24000 */ ++ 1.77636718750000000000e+00F, /* 0x3fe36000 */ ++ 1.78515625000000000000e+00F, /* 0x3fe48000 */ ++ 1.79394531250000000000e+00F, /* 0x3fe5a000 */ ++ 1.80273437500000000000e+00F, /* 0x3fe6c000 */ ++ 1.81127929687500000000e+00F, /* 0x3fe7d800 */ ++ 1.81982421875000000000e+00F, /* 0x3fe8f000 */ ++ 1.82836914062500000000e+00F, /* 0x3fea0800 */ ++ 1.83691406250000000000e+00F, /* 0x3feb2000 */ ++ 1.84545898437500000000e+00F, /* 0x3fec3800 */ ++ 1.85400390625000000000e+00F, /* 0x3fed5000 */ ++ 1.86230468750000000000e+00F, /* 0x3fee6000 */ ++ 1.87060546875000000000e+00F, /* 0x3fef7000 */ ++ 1.87915039062500000000e+00F, /* 0x3ff08800 */ ++ 1.88745117187500000000e+00F, /* 0x3ff19800 */ ++ 1.89550781250000000000e+00F, /* 0x3ff2a000 */ ++ 1.90380859375000000000e+00F, /* 0x3ff3b000 */ ++ 1.91210937500000000000e+00F, /* 0x3ff4c000 */ ++ 1.92016601562500000000e+00F, /* 0x3ff5c800 */ ++ 1.92822265625000000000e+00F, /* 0x3ff6d000 */ ++ 1.93627929687500000000e+00F, /* 0x3ff7d800 */ ++ 1.94433593750000000000e+00F, /* 0x3ff8e000 */ ++ 1.95239257812500000000e+00F, /* 0x3ff9e800 */ ++ 1.96044921875000000000e+00F, /* 0x3ffaf000 */ ++ 1.96826171875000000000e+00F, /* 0x3ffbf000 */ ++ 1.97631835937500000000e+00F, /* 0x3ffcf800 */ ++ 1.98413085937500000000e+00F, /* 0x3ffdf800 */ ++ 1.99194335937500000000e+00F, /* 0x3ffef800 */ ++ 2.00000000000000000000e+00F}; /* 0x40000000 */ ++ ++static const float rt_jby32_trail_table_float[97] = { ++ 0.00000000000000000000e+00F, /* 0x00000000 */ ++ 1.23941208585165441036e-04F, /* 0x3901f637 */ ++ 1.46876545841223560274e-05F, /* 0x37766aff */ ++ 1.70736297150142490864e-04F, /* 0x393307ad */ ++ 1.13296780909877270460e-04F, /* 0x38ed99bf */ ++ 9.53458802541717886925e-05F, /* 0x38c7f46e */ ++ 1.25126505736261606216e-04F, /* 0x39033464 */ ++ 2.10342666832730174065e-04F, /* 0x395c8f6e */ ++ 1.14066875539720058441e-04F, /* 0x38ef3730 */ ++ 8.72047676239162683487e-05F, /* 0x38b6e1b4 */ ++ 1.36111237225122749805e-04F, /* 0x390eb915 */ ++ 2.26244374061934649944e-05F, /* 0x37bdc99c */ ++ 2.40658700931817293167e-04F, /* 0x397c5954 */ ++ 6.31069415248930454254e-05F, /* 0x38845848 */ ++ 2.27412077947519719601e-04F, /* 0x396e7577 */ ++ 5.90185391047270968556e-06F, /* 0x36c6088a */ ++ 1.35496389702893793583e-04F, /* 0x390e1409 */ ++ 1.32179571664892137051e-04F, /* 0x390a99af */ ++ 0.00000000000000000000e+00F, /* 0x00000000 */ ++ 2.31086043640971183777e-04F, /* 0x39724fb0 */ ++ 9.66752704698592424393e-05F, /* 0x38cabe24 */ ++ 8.85332483449019491673e-05F, /* 0x38b9aaed */ ++ 2.09980673389509320259e-04F, /* 0x395c2e42 */ ++ 2.20044588786549866199e-04F, /* 0x3966bbc5 */ ++ 1.21749282698146998882e-04F, /* 0x38ff53a6 */ ++ 1.62125259521417319775e-04F, /* 0x392a002b */ ++ 9.97955357888713479042e-05F, /* 0x38d14952 */ ++ 1.81545779923908412457e-04F, /* 0x393e5d53 */ ++ 1.65768768056295812130e-04F, /* 0x392dd237 */ ++ 5.48927710042335093021e-05F, /* 0x38663caa */ ++ 9.53875860432162880898e-05F, /* 0x38c80ad2 */ ++ 4.53481625299900770187e-05F, /* 0x383e3438 */ ++ 1.51062369695864617825e-04F, /* 0x391e667f */ ++ 1.70453247847035527229e-04F, /* 0x3932bbb2 */ ++ 1.05505387182347476482e-04F, /* 0x38dd42c6 */ ++ 2.02269104192964732647e-04F, /* 0x39541833 */ ++ 2.18442466575652360916e-04F, /* 0x39650db4 */ ++ 1.55796806211583316326e-04F, /* 0x39235d63 */ ++ 1.60395247803535312414e-05F, /* 0x37868c9e */ ++ 4.49578510597348213196e-05F, /* 0x383c9120 */ ++ 0.00000000000000000000e+00F, /* 0x00000000 */ ++ 1.26840444863773882389e-04F, /* 0x39050079 */ ++ 1.82820076588541269302e-04F, /* 0x393fb364 */ ++ 1.69370483490638434887e-04F, /* 0x3931990b */ ++ 8.78757418831810355186e-05F, /* 0x38b849ee */ ++ 1.83815121999941766262e-04F, /* 0x3940be7f */ ++ 2.14343352126888930798e-04F, /* 0x3960c15b */ ++ 1.80714370799250900745e-04F, /* 0x393d7e25 */ ++ 8.41425862745381891727e-05F, /* 0x38b075b5 */ ++ 1.69945167726837098598e-04F, /* 0x3932334f */ ++ 1.95121858268976211548e-04F, /* 0x394c99a0 */ ++ 1.60778334247879683971e-04F, /* 0x3928969b */ ++ 6.79871009197086095810e-05F, /* 0x388e944c */ ++ 1.61929419846273958683e-04F, /* 0x3929cb99 */ ++ 1.99474830878898501396e-04F, /* 0x39512a1e */ ++ 1.81604162207804620266e-04F, /* 0x393e6cff */ ++ 1.09270178654696792364e-04F, /* 0x38e527fb */ ++ 2.27539261686615645885e-04F, /* 0x396e979b */ ++ 4.90300008095800876617e-05F, /* 0x384da590 */ ++ 6.28985289949923753738e-05F, /* 0x3883e864 */ ++ 2.58551553997676819563e-05F, /* 0x37d8e386 */ ++ 1.82868374395184218884e-04F, /* 0x393fc05b */ ++ 4.64625991298817098141e-05F, /* 0x3842e0d6 */ ++ 1.05703387816902250051e-04F, /* 0x38ddad13 */ ++ 1.17213814519345760345e-04F, /* 0x38f5d0b0 */ ++ 8.17377731436863541603e-05F, /* 0x38ab6aa2 */ ++ 0.00000000000000000000e+00F, /* 0x00000000 */ ++ 1.16847433673683553934e-04F, /* 0x38f50bfd */ ++ 1.88827965757809579372e-04F, /* 0x3946001f */ ++ 2.16612941585481166840e-04F, /* 0x39632298 */ ++ 2.00857131858356297016e-04F, /* 0x39529d2d */ ++ 1.42199307447299361229e-04F, /* 0x39151b56 */ ++ 4.12627305195201188326e-05F, /* 0x382d1185 */ ++ 1.42796401632949709892e-04F, /* 0x3915bb9e */ ++ 2.03253570361994206905e-04F, /* 0x39552077 */ ++ 2.23214170546270906925e-04F, /* 0x396a0e99 */ ++ 2.03244591830298304558e-04F, /* 0x39551e0e */ ++ 1.43898156238719820976e-04F, /* 0x3916e35e */ ++ 4.57155256299301981926e-05F, /* 0x383fbeac */ ++ 1.53365719597786664963e-04F, /* 0x3920d0cc */ ++ 2.23224633373320102692e-04F, /* 0x396a1168 */ ++ 1.16566716314991936088e-05F, /* 0x37439106 */ ++ 7.43694272387074306607e-06F, /* 0x36f98ada */ ++ 2.11048507480882108212e-04F, /* 0x395d4ce7 */ ++ 1.34682719362899661064e-04F, /* 0x390d399e */ ++ 2.29425968427676707506e-05F, /* 0x37c074da */ ++ 1.20421340398024767637e-04F, /* 0x38fc8ab7 */ ++ 1.83421318070031702518e-04F, /* 0x394054c9 */ ++ 2.12376224226318299770e-04F, /* 0x395eb14f */ ++ 2.07710763788782060146e-04F, /* 0x3959ccef */ ++ 1.69840845046564936638e-04F, /* 0x3932174e */ ++ 9.91739216260612010956e-05F, /* 0x38cffb98 */ ++ 2.40249748458154499531e-04F, /* 0x397beb8d */ ++ 1.05178231024183332920e-04F, /* 0x38dc9322 */ ++ 1.82623916771262884140e-04F, /* 0x393f7ebc */ ++ 2.28821940254420042038e-04F, /* 0x396fefec */ ++ 0.00000000000000000000e+00F}; /* 0x00000000 */ ++ ++ ++/* Handle special arguments first */ ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ ++ if(ax >= 0x7f800000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_SP32) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_SP32) ++ return nanf_with_flags(AMD_F_INVALID); ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ else if (ux & SIGNBIT_SP32) ++ { ++ /* x is negative. */ ++ if (x == 0.0F) ++ /* Handle negative zero first */ ++ return x; ++ else ++ return nanf_with_flags(AMD_F_INVALID); ++ } ++ else if (ux <= 0x007fffff) ++ { ++ /* x is denormalised or zero */ ++ if (ux == 0) ++ /* x is zero */ ++ return x; ++ else ++ { ++ /* x is denormalised; scale it up */ ++ /* Normalize x by increasing the exponent by 26 ++ and subtracting a correction to account for the implicit ++ bit. This replaces a slow denormalized ++ multiplication by a fast normal subtraction. */ ++ static const float corr = 7.888609052210118054e-31F; /* 0x0d800000 */ ++ denorm = 1; ++ GET_BITS_SP32(x, ux); ++ PUT_BITS_SP32(ux | 0x0d800000, x); ++ x -= corr; ++ GET_BITS_SP32(x, ux); ++ } ++ } ++ ++ /* Main algorithm */ ++ ++ /* ++ Find y and e such that x = 2^e * y, where y in [1,4). ++ This is done using an in-lined variant of splitFloat, ++ which also ensures that e is even. ++ */ ++ y = x; ++ ux &= EXPBITS_SP32; ++ ux >>= EXPSHIFTBITS_SP32; ++ if (ux & 1) ++ { ++ GET_BITS_SP32(y, u); ++ u &= (SIGNBIT_SP32 | MANTBITS_SP32); ++ u |= ONEEXPBITS_SP32; ++ PUT_BITS_SP32(u, y); ++ e = ux - EXPBIAS_SP32; ++ } ++ else ++ { ++ GET_BITS_SP32(y, u); ++ u &= (SIGNBIT_SP32 | MANTBITS_SP32); ++ u |= TWOEXPBITS_SP32; ++ PUT_BITS_SP32(u, y); ++ e = ux - EXPBIAS_SP32 - 1; ++ } ++ ++ /* Find the index of the sub-interval of [1,4) in which y lies. */ ++ ++ index = (int)(32.0F*y+0.5); ++ ++ /* Look up the table values and compute c and r = c/t */ ++ ++ rtc_lead = rt_jby32_lead_table_float[index-32]; ++ rtc_trail = rt_jby32_trail_table_float[index-32]; ++ c = 0.03125F*index; ++ r = (y - c)/c; ++ ++ /* ++ Find q = sqrt(1+r) - 1. ++ From one step of Newton on (q+1)^2 = 1+r ++ */ ++ ++ p = r*0.5F - r*r*(0.1250079870F - r*(0.6250522999e-01F)); ++ twop = p + p; ++ q = p - (p*p + (twop - r))/(twop + 2.0); ++ ++ /* Reconstruction */ ++ ++ rtc = rtc_lead + rtc_trail; ++ e >>= 1; /* e = e/2 */ ++ z = rtc_lead + (rtc*q+rtc_trail); ++ ++ if (denorm) ++ { ++ /* Scale by 2**(e-13) */ ++ PUT_BITS_SP32(((e - 13) + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, r); ++ z *= r; ++ } ++ else ++ { ++ /* Scale by 2**e */ ++ PUT_BITS_SP32((e + EXPBIAS_SP32) << EXPSHIFTBITS_SP32, r); ++ z *= r; ++ } ++ ++ return z; ++ ++} ++#endif /* SQRTF_AMD_INLINE */ ++ ++#ifdef USE_LOG_KERNEL_AMD ++static inline void log_kernel_amd64(double x, unsigned long ux, int *xexp, double *r1, double *r2) ++{ ++ ++ int expadjust; ++ double r, z1, z2, correction, f, f1, f2, q, u, v, poly; ++ int index; ++ ++ /* ++ Computes natural log(x). Algorithm based on: ++ Ping-Tak Peter Tang ++ "Table-driven implementation of the logarithm function in IEEE ++ floating-point arithmetic" ++ ACM Transactions on Mathematical Software (TOMS) ++ Volume 16, Issue 4 (December 1990) ++ */ ++ ++/* Arrays ln_lead_table and ln_tail_table contain ++ leading and trailing parts respectively of precomputed ++ values of natural log(1+i/64), for i = 0, 1, ..., 64. ++ ln_lead_table contains the first 24 bits of precision, ++ and ln_tail_table contains a further 53 bits precision. */ ++ ++ static const double ln_lead_table[65] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.55041813850402832031e-02, /* 0x3f8fc0a800000000 */ ++ 3.07716131210327148438e-02, /* 0x3f9f829800000000 */ ++ 4.58095073699951171875e-02, /* 0x3fa7745800000000 */ ++ 6.06245994567871093750e-02, /* 0x3faf0a3000000000 */ ++ 7.52233862876892089844e-02, /* 0x3fb341d700000000 */ ++ 8.96121263504028320312e-02, /* 0x3fb6f0d200000000 */ ++ 1.03796780109405517578e-01, /* 0x3fba926d00000000 */ ++ 1.17783010005950927734e-01, /* 0x3fbe270700000000 */ ++ 1.31576299667358398438e-01, /* 0x3fc0d77e00000000 */ ++ 1.45181953907012939453e-01, /* 0x3fc2955280000000 */ ++ 1.58604979515075683594e-01, /* 0x3fc44d2b00000000 */ ++ 1.71850204467773437500e-01, /* 0x3fc5ff3000000000 */ ++ 1.84922337532043457031e-01, /* 0x3fc7ab8900000000 */ ++ 1.97825729846954345703e-01, /* 0x3fc9525a80000000 */ ++ 2.10564732551574707031e-01, /* 0x3fcaf3c900000000 */ ++ 2.23143517971038818359e-01, /* 0x3fcc8ff780000000 */ ++ 2.35566020011901855469e-01, /* 0x3fce270700000000 */ ++ 2.47836112976074218750e-01, /* 0x3fcfb91800000000 */ ++ 2.59957492351531982422e-01, /* 0x3fd0a324c0000000 */ ++ 2.71933674812316894531e-01, /* 0x3fd1675c80000000 */ ++ 2.83768117427825927734e-01, /* 0x3fd22941c0000000 */ ++ 2.95464158058166503906e-01, /* 0x3fd2e8e280000000 */ ++ 3.07025015354156494141e-01, /* 0x3fd3a64c40000000 */ ++ 3.18453729152679443359e-01, /* 0x3fd4618bc0000000 */ ++ 3.29753279685974121094e-01, /* 0x3fd51aad80000000 */ ++ 3.40926527976989746094e-01, /* 0x3fd5d1bd80000000 */ ++ 3.51976394653320312500e-01, /* 0x3fd686c800000000 */ ++ 3.62905442714691162109e-01, /* 0x3fd739d7c0000000 */ ++ 3.73716354370117187500e-01, /* 0x3fd7eaf800000000 */ ++ 3.84411692619323730469e-01, /* 0x3fd89a3380000000 */ ++ 3.94993782043457031250e-01, /* 0x3fd9479400000000 */ ++ 4.05465066432952880859e-01, /* 0x3fd9f323c0000000 */ ++ 4.15827870368957519531e-01, /* 0x3fda9cec80000000 */ ++ 4.26084339618682861328e-01, /* 0x3fdb44f740000000 */ ++ 4.36236739158630371094e-01, /* 0x3fdbeb4d80000000 */ ++ 4.46287095546722412109e-01, /* 0x3fdc8ff7c0000000 */ ++ 4.56237375736236572266e-01, /* 0x3fdd32fe40000000 */ ++ 4.66089725494384765625e-01, /* 0x3fddd46a00000000 */ ++ 4.75845873355865478516e-01, /* 0x3fde744240000000 */ ++ 4.85507786273956298828e-01, /* 0x3fdf128f40000000 */ ++ 4.95077252388000488281e-01, /* 0x3fdfaf5880000000 */ ++ 5.04556000232696533203e-01, /* 0x3fe02552a0000000 */ ++ 5.13945698738098144531e-01, /* 0x3fe0723e40000000 */ ++ 5.23248136043548583984e-01, /* 0x3fe0be72e0000000 */ ++ 5.32464742660522460938e-01, /* 0x3fe109f380000000 */ ++ 5.41597247123718261719e-01, /* 0x3fe154c3c0000000 */ ++ 5.50647079944610595703e-01, /* 0x3fe19ee6a0000000 */ ++ 5.59615731239318847656e-01, /* 0x3fe1e85f40000000 */ ++ 5.68504691123962402344e-01, /* 0x3fe23130c0000000 */ ++ 5.77315330505371093750e-01, /* 0x3fe2795e00000000 */ ++ 5.86049020290374755859e-01, /* 0x3fe2c0e9e0000000 */ ++ 5.94707071781158447266e-01, /* 0x3fe307d720000000 */ ++ 6.03290796279907226562e-01, /* 0x3fe34e2880000000 */ ++ 6.11801505088806152344e-01, /* 0x3fe393e0c0000000 */ ++ 6.20240390300750732422e-01, /* 0x3fe3d90260000000 */ ++ 6.28608644008636474609e-01, /* 0x3fe41d8fe0000000 */ ++ 6.36907458305358886719e-01, /* 0x3fe4618bc0000000 */ ++ 6.45137906074523925781e-01, /* 0x3fe4a4f840000000 */ ++ 6.53301239013671875000e-01, /* 0x3fe4e7d800000000 */ ++ 6.61398470401763916016e-01, /* 0x3fe52a2d20000000 */ ++ 6.69430613517761230469e-01, /* 0x3fe56bf9c0000000 */ ++ 6.77398800849914550781e-01, /* 0x3fe5ad4040000000 */ ++ 6.85303986072540283203e-01, /* 0x3fe5ee02a0000000 */ ++ 6.93147122859954833984e-01}; /* 0x3fe62e42e0000000 */ ++ ++ static const double ln_tail_table[65] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 5.15092497094772879206e-09, /* 0x3e361f807c79f3db */ ++ 4.55457209735272790188e-08, /* 0x3e6873c1980267c8 */ ++ 2.86612990859791781788e-08, /* 0x3e5ec65b9f88c69e */ ++ 2.23596477332056055352e-08, /* 0x3e58022c54cc2f99 */ ++ 3.49498983167142274770e-08, /* 0x3e62c37a3a125330 */ ++ 3.23392843005887000414e-08, /* 0x3e615cad69737c93 */ ++ 1.35722380472479366661e-08, /* 0x3e4d256ab1b285e9 */ ++ 2.56504325268044191098e-08, /* 0x3e5b8abcb97a7aa2 */ ++ 5.81213608741512136843e-08, /* 0x3e6f34239659a5dc */ ++ 5.59374849578288093334e-08, /* 0x3e6e07fd48d30177 */ ++ 5.06615629004996189970e-08, /* 0x3e6b32df4799f4f6 */ ++ 5.24588857848400955725e-08, /* 0x3e6c29e4f4f21cf8 */ ++ 9.61968535632653505972e-10, /* 0x3e1086c848df1b59 */ ++ 1.34829655346594463137e-08, /* 0x3e4cf456b4764130 */ ++ 3.65557749306383026498e-08, /* 0x3e63a02ffcb63398 */ ++ 3.33431709374069198903e-08, /* 0x3e61e6a6886b0976 */ ++ 5.13008650536088382197e-08, /* 0x3e6b8abcb97a7aa2 */ ++ 5.09285070380306053751e-08, /* 0x3e6b578f8aa35552 */ ++ 3.20853940845502057341e-08, /* 0x3e6139c871afb9fc */ ++ 4.06713248643004200446e-08, /* 0x3e65d5d30701ce64 */ ++ 5.57028186706125221168e-08, /* 0x3e6de7bcb2d12142 */ ++ 5.48356693724804282546e-08, /* 0x3e6d708e984e1664 */ ++ 1.99407553679345001938e-08, /* 0x3e556945e9c72f36 */ ++ 1.96585517245087232086e-09, /* 0x3e20e2f613e85bda */ ++ 6.68649386072067321503e-09, /* 0x3e3cb7e0b42724f6 */ ++ 5.89936034642113390002e-08, /* 0x3e6fac04e52846c7 */ ++ 2.85038578721554472484e-08, /* 0x3e5e9b14aec442be */ ++ 5.09746772910284482606e-08, /* 0x3e6b5de8034e7126 */ ++ 5.54234668933210171467e-08, /* 0x3e6dc157e1b259d3 */ ++ 6.29100830926604004874e-09, /* 0x3e3b05096ad69c62 */ ++ 2.61974119468563937716e-08, /* 0x3e5c2116faba4cdd */ ++ 4.16752115011186398935e-08, /* 0x3e665fcc25f95b47 */ ++ 2.47747534460820790327e-08, /* 0x3e5a9a08498d4850 */ ++ 5.56922172017964209793e-08, /* 0x3e6de647b1465f77 */ ++ 2.76162876992552906035e-08, /* 0x3e5da71b7bf7861d */ ++ 7.08169709942321478061e-09, /* 0x3e3e6a6886b09760 */ ++ 5.77453510221151779025e-08, /* 0x3e6f0075eab0ef64 */ ++ 4.43021445893361960146e-09, /* 0x3e33071282fb989b */ ++ 3.15140984357495864573e-08, /* 0x3e60eb43c3f1bed2 */ ++ 2.95077445089736670973e-08, /* 0x3e5faf06ecb35c84 */ ++ 1.44098510263167149349e-08, /* 0x3e4ef1e63db35f68 */ ++ 1.05196987538551827693e-08, /* 0x3e469743fb1a71a5 */ ++ 5.23641361722697546261e-08, /* 0x3e6c1cdf404e5796 */ ++ 7.72099925253243069458e-09, /* 0x3e4094aa0ada625e */ ++ 5.62089493829364197156e-08, /* 0x3e6e2d4c96fde3ec */ ++ 3.53090261098577946927e-08, /* 0x3e62f4d5e9a98f34 */ ++ 3.80080516835568242269e-08, /* 0x3e6467c96ecc5cbe */ ++ 5.66961038386146408282e-08, /* 0x3e6e7040d03dec5a */ ++ 4.42287063097349852717e-08, /* 0x3e67bebf4282de36 */ ++ 3.45294525105681104660e-08, /* 0x3e6289b11aeb783f */ ++ 2.47132034530447431509e-08, /* 0x3e5a891d1772f538 */ ++ 3.59655343422487209774e-08, /* 0x3e634f10be1fb591 */ ++ 5.51581770357780862071e-08, /* 0x3e6d9ce1d316eb93 */ ++ 3.60171867511861372793e-08, /* 0x3e63562a19a9c442 */ ++ 1.94511067964296180547e-08, /* 0x3e54e2adf548084c */ ++ 1.54137376631349347838e-08, /* 0x3e508ce55cc8c97a */ ++ 3.93171034490174464173e-09, /* 0x3e30e2f613e85bda */ ++ 5.52990607758839766440e-08, /* 0x3e6db03ebb0227bf */ ++ 3.29990737637586136511e-08, /* 0x3e61b75bb09cb098 */ ++ 1.18436010922446096216e-08, /* 0x3e496f16abb9df22 */ ++ 4.04248680368301346709e-08, /* 0x3e65b3f399411c62 */ ++ 2.27418915900284316293e-08, /* 0x3e586b3e59f65355 */ ++ 1.70263791333409206020e-08, /* 0x3e52482ceae1ac12 */ ++ 5.76999904754328540596e-08}; /* 0x3e6efa39ef35793c */ ++ ++ /* Approximating polynomial coefficients for x near 1.0 */ ++ static const double ++ ca_1 = 8.33333333333317923934e-02, /* 0x3fb55555555554e6 */ ++ ca_2 = 1.25000000037717509602e-02, /* 0x3f89999999bac6d4 */ ++ ca_3 = 2.23213998791944806202e-03, /* 0x3f62492307f1519f */ ++ ca_4 = 4.34887777707614552256e-04; /* 0x3f3c8034c85dfff0 */ ++ ++ /* Approximating polynomial coefficients for other x */ ++ static const double ++ cb_1 = 8.33333333333333593622e-02, /* 0x3fb5555555555557 */ ++ cb_2 = 1.24999999978138668903e-02, /* 0x3f89999999865ede */ ++ cb_3 = 2.23219810758559851206e-03; /* 0x3f6249423bd94741 */ ++ ++ static const unsigned long ++ log_thresh1 = 0x3fee0faa00000000, ++ log_thresh2 = 0x3ff1082c00000000; ++ ++ /* log_thresh1 = 9.39412117004394531250e-1 = 0x3fee0faa00000000 ++ log_thresh2 = 1.06449508666992187500 = 0x3ff1082c00000000 */ ++ if (ux >= log_thresh1 && ux <= log_thresh2) ++ { ++ /* Arguments close to 1.0 are handled separately to maintain ++ accuracy. ++ ++ The approximation in this region exploits the identity ++ log( 1 + r ) = log( 1 + u/2 ) / log( 1 - u/2 ), where ++ u = 2r / (2+r). ++ Note that the right hand side has an odd Taylor series expansion ++ which converges much faster than the Taylor series expansion of ++ log( 1 + r ) in r. Thus, we approximate log( 1 + r ) by ++ u + A1 * u^3 + A2 * u^5 + ... + An * u^(2n+1). ++ ++ One subtlety is that since u cannot be calculated from ++ r exactly, the rounding error in the first u should be ++ avoided if possible. To accomplish this, we observe that ++ u = r - r*r/(2+r). ++ Since x (=1+r) is the input argument, and thus presumed exact, ++ the formula above approximates u accurately because ++ u = r - correction, ++ and the magnitude of "correction" (of the order of r*r) ++ is small. ++ With these observations, we will approximate log( 1 + r ) by ++ r + ( (A1*u^3 + ... + An*u^(2n+1)) - correction ). ++ ++ We approximate log(1+r) by an odd polynomial in u, where ++ u = 2r/(2+r) = r - r*r/(2+r). ++ */ ++ r = x - 1.0; ++ u = r / (2.0 + r); ++ correction = r * u; ++ u = u + u; ++ v = u * u; ++ z1 = r; ++ z2 = (u * v * (ca_1 + v * (ca_2 + v * (ca_3 + v * ca_4))) - correction); ++ *r1 = z1; ++ *r2 = z2; ++ *xexp = 0; ++ } ++ else ++ { ++ /* ++ First, we decompose the argument x to the form ++ x = 2**M * (F1 + F2), ++ where 1 <= F1+F2 < 2, M has the value of an integer, ++ F1 = 1 + j/64, j ranges from 0 to 64, and |F2| <= 1/128. ++ ++ Second, we approximate log( 1 + F2/F1 ) by an odd polynomial ++ in U, where U = 2 F2 / (2 F2 + F1). ++ Note that log( 1 + F2/F1 ) = log( 1 + U/2 ) - log( 1 - U/2 ). ++ The core approximation calculates ++ Poly = [log( 1 + U/2 ) - log( 1 - U/2 )]/U - 1. ++ Note that log(1 + U/2) - log(1 - U/2) = 2 arctanh ( U/2 ), ++ thus, Poly = 2 arctanh( U/2 ) / U - 1. ++ ++ It is not hard to see that ++ log(x) = M*log(2) + log(F1) + log( 1 + F2/F1 ). ++ Hence, we return Z1 = log(F1), and Z2 = log( 1 + F2/F1). ++ The values of log(F1) are calculated beforehand and stored ++ in the program. ++ */ ++ ++ f = x; ++ if (ux < IMPBIT_DP64) ++ { ++ /* The input argument x is denormalized */ ++ /* Normalize f by increasing the exponent by 60 ++ and subtracting a correction to account for the implicit ++ bit. This replaces a slow denormalized ++ multiplication by a fast normal subtraction. */ ++ static const double corr = 2.5653355008114851558350183e-290; /* 0x03d0000000000000 */ ++ GET_BITS_DP64(f, ux); ++ ux |= 0x03d0000000000000; ++ PUT_BITS_DP64(ux, f); ++ f -= corr; ++ GET_BITS_DP64(f, ux); ++ expadjust = 60; ++ } ++ else ++ expadjust = 0; ++ ++ /* Store the exponent of x in xexp and put ++ f into the range [0.5,1) */ ++ *xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64 - expadjust; ++ PUT_BITS_DP64((ux & MANTBITS_DP64) | HALFEXPBITS_DP64, f); ++ ++ /* Now x = 2**xexp * f, 1/2 <= f < 1. */ ++ ++ /* Set index to be the nearest integer to 128*f */ ++ r = 128.0 * f; ++ index = (int)(r + 0.5); ++ ++ z1 = ln_lead_table[index-64]; ++ q = ln_tail_table[index-64]; ++ f1 = index * 0.0078125; /* 0.0078125 = 1/128 */ ++ f2 = f - f1; ++ /* At this point, x = 2**xexp * ( f1 + f2 ) where ++ f1 = j/128, j = 64, 65, ..., 128 and |f2| <= 1/256. */ ++ ++ /* Calculate u = 2 f2 / ( 2 f1 + f2 ) = f2 / ( f1 + 0.5*f2 ) */ ++ /* u = f2 / (f1 + 0.5 * f2); */ ++ u = f2 / (f1 + 0.5 * f2); ++ ++ /* Here, |u| <= 2(exp(1/16)-1) / (exp(1/16)+1). ++ The core approximation calculates ++ poly = [log(1 + u/2) - log(1 - u/2)]/u - 1 */ ++ v = u * u; ++ poly = (v * (cb_1 + v * (cb_2 + v * cb_3))); ++ z2 = q + (u + u * poly); ++ *r1 = z1; ++ *r2 = z2; ++ } ++ return; ++} ++#endif /* USE_LOG_KERNEL_AMD */ ++ ++#if defined(USE_REMAINDER_PIBY2F_INLINE) ++/* Define this to get debugging print statements activated */ ++#define DEBUGGING_PRINT ++#undef DEBUGGING_PRINT ++ ++ ++#ifdef DEBUGGING_PRINT ++#include <stdio.h> ++char *d2b(long d, int bitsper, int point) ++{ ++ static char buff[200]; ++ int i, j; ++ j = bitsper; ++ if (point >= 0 && point <= bitsper) ++ j++; ++ buff[j] = '\0'; ++ for (i = bitsper - 1; i >= 0; i--) ++ { ++ j--; ++ if (d % 2 == 1) ++ buff[j] = '1'; ++ else ++ buff[j] = '0'; ++ if (i == point) ++ { ++ j--; ++ buff[j] = '.'; ++ } ++ d /= 2; ++ } ++ return buff; ++} ++#endif ++ ++/* Given positive argument x, reduce it to the range [-pi/4,pi/4] using ++ extra precision, and return the result in r. ++ Return value "region" tells how many lots of pi/2 were subtracted ++ from x to put it in the range [-pi/4,pi/4], mod 4. */ ++static inline void __remainder_piby2f_inline(double x, unsigned long ux, double *r, int *region) ++{ ++ ++ /* eleven_piby4 is the closest machine number BELOW 11*pi/4 */ ++ static const double ++ eleven_piby4 = 8.6393797973719301808159e+00; /* 0x4021475cc9eedf00 */ ++ ++ static const double ++ piby2 = 1.57079632679489655800e+00, /* 0x3ff921fb54442d18 */ ++ twobypi = 6.36619772367581382433e-01, /* 0x3fe45f306dc9c883 */ ++ pi = 3.14159265358979311600e+00, /* 0x400921fb54442d18 */ ++ three_piby2 = 4.71238898038468967400e+00, /* 0x4012d97c7f3321d2 */ ++ two_pi = 6.28318530717958623200e+00, /* 0x401921fb54442d18 */ ++ five_piby2 = 7.85398163397448278999e+00; /* 0x401f6a7a2955385e */ ++ ++ /* Each of these threshold values is the closest machine ++ number BELOW a multiple of pi/4, i.e. they are not ++ rounded to nearest. thresh1 is 1*pi/4, thresh3 is 3*pi/4, etc. ++ This ensures that we end up in precisely the correct region. */ ++ static const double ++ thresh1 = 7.8539816339744827899949e-01, /* 0x3fe921fb54442d18 */ ++ thresh3 = 2.3561944901923448369984e+00, /* 0x4002d97c7f3321d2 */ ++ thresh5 = 3.9269908169872413949974e+00, /* 0x400f6a7a2955385e */ ++ thresh7 = 5.4977871437821379529964e+00, /* 0x4015fdbbe9bba775 */ ++ thresh9 = 7.0685834705770345109954e+00; /* 0x401c463abeccb2bb */ ++ ++ static const double cancellationThresh = 1.0e-5; ++ int done = 0; ++ ++ /* For small values of x, up to 11*pi/4, we do double precision ++ subtraction of the relevant multiple of pi/2 */ ++ if (x <= eleven_piby4) /* x <= 11*pi/4 */ ++ { ++ double t, ctest; ++ ++ if (x <= thresh5) /* x < 5*pi/4 */ ++ { ++ if (x <= thresh1) /* x < pi/4 */ ++ { ++ /* Quick return if x is already less than pi/4 */ ++ *r = x; ++ *region = 0; ++ return; ++ } ++ else if (x <= thresh3) /* x < 3*pi/4 */ ++ { ++ t = x - piby2; ++ *region = 1; ++ } ++ else /* x < 5*pi/4 */ ++ { ++ t = x - pi; ++ *region = 2; ++ } ++ } ++ else ++ { ++ if (x <= thresh7) /* x < 7*pi/4 */ ++ { ++ t = x - three_piby2; ++ *region = 3; ++ } ++ else if (x <= thresh9) /* x < 9*pi/4 */ ++ { ++ t = x - two_pi; ++ *region = 0; ++ } ++ else /* x < 11*pi/4 */ ++ { ++ t = x - five_piby2; ++ *region = 1; ++ } ++ } ++ ++ /* Check for massive cancellation which may happen very close ++ to multiples of pi/2 */ ++ if (t < 0.0) ++ ctest = -t; ++ else ++ ctest = t; ++#ifdef DEBUGGING_PRINT ++ printf("Cancellation threshold test = (%g > %g)\n", ++ ctest, cancellationThresh); ++#endif ++ ++ /* Check if cancellation error was not too large */ ++ if (ctest > cancellationThresh) ++ { ++ *r = t; ++ done = 1; ++ } ++ /* Otherwise fall through to the expensive method */ ++ } ++ else if (x <= 1.0e6) ++ { ++ /* This range reduction is accurate enough for x up to ++ approximately 2**(20) except near multiples of pi/2 */ ++ ++ /* We perform double precision arithmetic to find the ++ nearest multiple of pi/2 to x */ ++ int reg; ++ double z, w, c, ctest; ++ ++ /* Multiply x by 2/pi in double precision, result in z */ ++ z = x * twobypi; ++ ++#ifdef DEBUGGING_PRINT ++ printf("z = %30.20e = %s\n", z, double2hex(&z)); ++#endif ++ ++ /* Find reg, the nearest integer to z */ ++ reg = (int)(z + 0.5); ++ ++#ifdef DEBUGGING_PRINT ++ printf("reg = %d\n", reg); ++#endif ++ ++ /* Subtract reg from z, result in w */ ++ w = z - reg; ++ ++#ifdef DEBUGGING_PRINT ++ printf("w = %30.20e = %s\n", w, double2hex(&w)); ++#endif ++ ++ /* Check for massive cancellation which may happen very close ++ to multiples of pi/2 */ ++ if (w < 0.0) ++ ctest = -w; ++ else ++ ctest = w; ++ ++ /* If cancellation is not too severe, continue with this method. ++ Otherwise we fall through to the expensive, accurate method */ ++ if (ctest > cancellationThresh) ++ { ++ /* Multiply w by pi/2 */ ++ c = w * piby2; ++ *r = c; ++ *region = reg & 3; ++ ++#ifdef DEBUGGING_PRINT ++ printf("r = %30.20e = %s\n", *r, double2hex(r)); ++#endif ++ done = 1; ++ } ++ } ++ ++ if (!done) ++ { ++ /* This method simulates multi-precision floating-point ++ arithmetic and is accurate for all 1 <= x < infinity */ ++#if 0 ++ const int bitsper = 36; ++#else ++#define bitsper 36 ++#endif ++ unsigned long res[10]; ++ unsigned long u, carry, mask, mant, nextbits; ++ int first, last, i, rexp, xexp, resexp, ltb, determ, bc; ++ double dx; ++ static const double ++ piby2 = 1.57079632679489655800e+00; /* 0x3ff921fb54442d18 */ ++ static unsigned long pibits[] = ++ { ++ 0L, ++ 5215L, 13000023176L, 11362338026L, 67174558139L, ++ 34819822259L, 10612056195L, 67816420731L, 57840157550L, ++ 19558516809L, 50025467026L, 25186875954L, 18152700886L ++ }; ++ ++#ifdef DEBUGGING_PRINT ++ printf("On entry, x = %25.20e = %s\n", x, double2hex(&x)); ++#endif ++ ++ xexp = (int)(((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64); ++ ux = ((ux & MANTBITS_DP64) | IMPBIT_DP64) >> 29; ++ ++#ifdef DEBUGGING_PRINT ++ printf("ux = %s\n", d2b(ux, 64, -1)); ++#endif ++ ++ /* Now ux is the mantissa bit pattern of x as a long integer */ ++ mask = (1L << bitsper) - 1; ++ ++ /* Set first and last to the positions of the first ++ and last chunks of 2/pi that we need */ ++ first = xexp / bitsper; ++ resexp = xexp - first * bitsper; ++ /* 120 is the theoretical maximum number of bits (actually ++ 115 for IEEE single precision) that we need to extract ++ from the middle of 2/pi to compute the reduced argument ++ accurately enough for our purposes */ ++ last = first + 120 / bitsper; ++ ++#ifdef DEBUGGING_PRINT ++ printf("first = %d, last = %d\n", first, last); ++#endif ++ ++ /* Do a long multiplication of the bits of 2/pi by the ++ integer mantissa */ ++#if 0 ++ for (i = last; i >= first; i--) ++ { ++ u = pibits[i] * ux + carry; ++ res[i - first] = u & mask; ++ carry = u >> bitsper; ++ } ++ res[last - first + 1] = 0; ++#else ++ /* Unroll the loop. This is only correct because we know ++ that bitsper is fixed as 36. */ ++ res[4] = 0; ++ u = pibits[last] * ux; ++ res[3] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last - 1] * ux + carry; ++ res[2] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last - 2] * ux + carry; ++ res[1] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[first] * ux + carry; ++ res[0] = u & mask; ++#endif ++ ++#ifdef DEBUGGING_PRINT ++ printf("resexp = %d\n", resexp); ++ printf("Significant part of x * 2/pi with binary" ++ " point in correct place:\n"); ++ for (i = 0; i <= last - first; i++) ++ { ++ if (i > 0 && i % 5 == 0) ++ printf("\n "); ++ if (i == 1) ++ printf("%s ", d2b(res[i], bitsper, resexp)); ++ else ++ printf("%s ", d2b(res[i], bitsper, -1)); ++ } ++ printf("\n"); ++#endif ++ ++ /* Reconstruct the result */ ++ ltb = (int)((((res[0] << bitsper) | res[1]) ++ >> (bitsper - 1 - resexp)) & 7); ++ ++ /* determ says whether the fractional part is >= 0.5 */ ++ determ = ltb & 1; ++ ++#ifdef DEBUGGING_PRINT ++ printf("ltb = %d (last two bits before binary point" ++ " and first bit after)\n", ltb); ++ printf("determ = %d (1 means need to negate because the fractional\n" ++ " part of x * 2/pi is greater than 0.5)\n", determ); ++#endif ++ ++ i = 1; ++ if (determ) ++ { ++ /* The mantissa is >= 0.5. We want to subtract it ++ from 1.0 by negating all the bits */ ++ *region = ((ltb >> 1) + 1) & 3; ++ mant = ~(res[1]) & ((1L << (bitsper - resexp)) - 1); ++ while (mant < 0x0000000000010000) ++ { ++ i++; ++ mant = (mant << bitsper) | (~(res[i]) & mask); ++ } ++ nextbits = (~(res[i+1]) & mask); ++ } ++ else ++ { ++ *region = (ltb >> 1); ++ mant = res[1] & ((1L << (bitsper - resexp)) - 1); ++ while (mant < 0x0000000000010000) ++ { ++ i++; ++ mant = (mant << bitsper) | res[i]; ++ } ++ nextbits = res[i+1]; ++ } ++ ++#ifdef DEBUGGING_PRINT ++ printf("First bits of mant = %s\n", d2b(mant, bitsper, -1)); ++#endif ++ ++ /* Normalize the mantissa. The shift value 6 here, determined by ++ trial and error, seems to give optimal speed. */ ++ bc = 0; ++ while (mant < 0x0000400000000000) ++ { ++ bc += 6; ++ mant <<= 6; ++ } ++ while (mant < 0x0010000000000000) ++ { ++ bc++; ++ mant <<= 1; ++ } ++ mant |= nextbits >> (bitsper - bc); ++ ++ rexp = 52 + resexp - bc - i * bitsper; ++ ++#ifdef DEBUGGING_PRINT ++ printf("Normalised mantissa = 0x%016lx\n", mant); ++ printf("Exponent to be inserted on mantissa = rexp = %d\n", rexp); ++#endif ++ ++ /* Put the result exponent rexp onto the mantissa pattern */ ++ u = ((unsigned long)rexp + EXPBIAS_DP64) << EXPSHIFTBITS_DP64; ++ ux = (mant & MANTBITS_DP64) | u; ++ if (determ) ++ /* If we negated the mantissa we negate x too */ ++ ux |= SIGNBIT_DP64; ++ PUT_BITS_DP64(ux, dx); ++ ++#ifdef DEBUGGING_PRINT ++ printf("(x*2/pi) = %25.20e = %s\n", dx, double2hex(&dx)); ++#endif ++ ++ /* x is a double precision version of the fractional part of ++ x * 2 / pi. Multiply x by pi/2 in double precision ++ to get the reduced argument r. */ ++ *r = dx * piby2; ++ ++#ifdef DEBUGGING_PRINT ++ printf(" r = frac(x*2/pi) * pi/2:\n"); ++ printf(" r = %25.20e = %s\n", *r, double2hex(r)); ++ printf("region = (number of pi/2 subtracted from x) mod 4 = %d\n", ++ *region); ++#endif ++ } ++} ++#endif /* USE_REMAINDER_PIBY2F_INLINE */ ++ ++#endif /* LIBM_INLINES_AMD_H_INCLUDED */ +diff -urpN libc/sysdeps/x86_64/fpu/libm_util_amd.h libc-amd/sysdeps/x86_64/fpu/libm_util_amd.h +--- libc/sysdeps/x86_64/fpu/libm_util_amd.h 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/libm_util_amd.h 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,101 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#ifndef LIBM_UTIL_AMD_H_INCLUDED ++#define LIBM_UTIL_AMD_H_INCLUDED 1 ++ ++/* Compile-time verification that type long is the same size ++ as type double (i.e. we are really on a 64-bit machine) */ ++void check_long_against_double_size(int machine_is_64_bit[(sizeof(long) == sizeof(double))?1:-1]); ++ ++ ++/* Definitions for double functions on 64 bit machines */ ++#define SIGNBIT_DP64 0x8000000000000000 ++#define EXPBITS_DP64 0x7ff0000000000000 ++#define MANTBITS_DP64 0x000fffffffffffff ++#define ONEEXPBITS_DP64 0x3ff0000000000000 ++#define TWOEXPBITS_DP64 0x4000000000000000 ++#define HALFEXPBITS_DP64 0x3fe0000000000000 ++#define IMPBIT_DP64 0x0010000000000000 ++#define QNANBITPATT_DP64 0x7ff8000000000000 ++#define PINFBITPATT_DP64 0x7ff0000000000000 ++#define NINFBITPATT_DP64 0xfff0000000000000 ++#define EXPBIAS_DP64 1023 ++#define EXPSHIFTBITS_DP64 52 ++#define BIASEDEMIN_DP64 1 ++#define EMIN_DP64 -1022 ++#define BIASEDEMAX_DP64 2046 ++#define EMAX_DP64 1023 ++#define LAMBDA_DP64 1.0e300 ++#define MANTLENGTH_DP64 53 ++#define BASEDIGITS_DP64 15 ++ ++ ++/* These definitions, used by float functions, ++ are for both 32 and 64 bit machines */ ++#define SIGNBIT_SP32 0x80000000 ++#define EXPBITS_SP32 0x7f800000 ++#define MANTBITS_SP32 0x007fffff ++#define ONEEXPBITS_SP32 0x3f800000 ++#define TWOEXPBITS_SP32 0x40000000 ++#define HALFEXPBITS_SP32 0x3f000000 ++#define IMPBIT_SP32 0x00800000 ++#define QNANBITPATT_SP32 0x7fc00000 ++#define PINFBITPATT_SP32 0x7f800000 ++#define NINFBITPATT_SP32 0xff800000 ++#define EXPBIAS_SP32 127 ++#define EXPSHIFTBITS_SP32 23 ++#define BIASEDEMIN_SP32 1 ++#define EMIN_SP32 -126 ++#define BIASEDEMAX_SP32 254 ++#define EMAX_SP32 127 ++#define LAMBDA_SP32 1.0e30 ++#define MANTLENGTH_SP32 24 ++#define BASEDIGITS_SP32 7 ++ ++#define CLASS_SIGNALLING_NAN 1 ++#define CLASS_QUIET_NAN 2 ++#define CLASS_NEGATIVE_INFINITY 3 ++#define CLASS_NEGATIVE_NORMAL_NONZERO 4 ++#define CLASS_NEGATIVE_DENORMAL 5 ++#define CLASS_NEGATIVE_ZERO 6 ++#define CLASS_POSITIVE_ZERO 7 ++#define CLASS_POSITIVE_DENORMAL 8 ++#define CLASS_POSITIVE_NORMAL_NONZERO 9 ++#define CLASS_POSITIVE_INFINITY 10 ++ ++#define OLD_BITS_SP32(x) (*((unsigned int *)&x)) ++#define OLD_BITS_DP64(x) (*((unsigned long *)&x)) ++ ++/* Alternatives to the above functions which don't have ++ problems when using high optimization levels on gcc */ ++#define GET_BITS_SP32(x, ux) {union {float f; unsigned int i;} _bitsy; _bitsy.f = (x); ux = _bitsy.i;} ++#define PUT_BITS_SP32(ux, x) {union {float f; unsigned int i;} _bitsy; _bitsy.i = (ux); x = _bitsy.f;} ++#define GET_BITS_DP64(x, ux) {union {double d; unsigned long i;} _bitsy; _bitsy.d = (x); ux = _bitsy.i;} ++#define PUT_BITS_DP64(ux, x) {union {double d; unsigned long i;} _bitsy; _bitsy.i = (ux); x = _bitsy.d;} ++ ++ ++/* Processor-dependent floating-point status flags */ ++#define AMD_F_INEXACT 0x00000020 ++#define AMD_F_UNDERFLOW 0x00000010 ++#define AMD_F_OVERFLOW 0x00000008 ++#define AMD_F_DIVBYZERO 0x00000004 ++#define AMD_F_INVALID 0x00000001 ++ ++/* Processor-dependent floating-point precision-control flags */ ++#define AMD_F_EXTENDED 0x00000300 ++#define AMD_F_DOUBLE 0x00000200 ++#define AMD_F_SINGLE 0x00000000 ++ ++/* Processor-dependent floating-point rounding-control flags */ ++#define AMD_F_RC_NEAREST 0x00000000 ++#define AMD_F_RC_DOWN 0x00002000 ++#define AMD_F_RC_UP 0x00004000 ++#define AMD_F_RC_ZERO 0x00006000 ++ ++#endif /* LIBM_UTIL_AMD_H_INCLUDED */ +diff -urpN libc/sysdeps/x86_64/fpu/Makefile libc-amd/sysdeps/x86_64/fpu/Makefile +--- libc/sysdeps/x86_64/fpu/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/Makefile 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,3 @@ ++ifeq ($(subdir),math) ++libm-sysdep_routines += w_remainder_piby2 w_remainder_piby2f ++endif +diff -urpN libc/sysdeps/x86_64/fpu/s_atan2.c libc-amd/sysdeps/x86_64/fpu/s_atan2.c +--- libc/sysdeps/x86_64/fpu/s_atan2.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_atan2.c 2006-03-22 02:03:46.000000000 +0100 +@@ -0,0 +1,746 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VAL_WITH_FLAGS ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_SCALEUPDOUBLE1024 ++#define USE_SCALEDOWNDOUBLE ++#include "libm_inlines_amd.h" ++#undef USE_SCALEDOWNDOUBLE ++#undef USE_SCALEUPDOUBLE1024 ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range arguments ++ (only used when _LIB_VERSION is _SVID_) */ ++static inline double retval_errno_edom(double x, double y) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = y; ++ exc.type = DOMAIN; ++ exc.name = (char *)"atan2"; ++ exc.retval = HUGE; ++ if (!matherr(&exc)) ++ { ++ (void)fputs("atan2: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++double __atan2(double y, double x) ++{ ++ /* Arrays atan_jby256_lead and atan_jby256_tail contain ++ leading and trailing parts respectively of precomputed ++ values of atan(j/256), for j = 16, 17, ..., 256. ++ atan_jby256_lead contains the first 21 bits of precision, ++ and atan_jby256_tail contains a further 53 bits precision. */ ++ ++ static const double atan_jby256_lead[ 241] = { ++ 6.24187886714935302734e-02, /* 0x3faff55b00000000 */ ++ 6.63088560104370117188e-02, /* 0x3fb0f99e00000000 */ ++ 7.01969265937805175781e-02, /* 0x3fb1f86d00000000 */ ++ 7.40829110145568847656e-02, /* 0x3fb2f71900000000 */ ++ 7.79666304588317871094e-02, /* 0x3fb3f59f00000000 */ ++ 8.18479657173156738281e-02, /* 0x3fb4f3fd00000000 */ ++ 8.57268571853637695312e-02, /* 0x3fb5f23200000000 */ ++ 8.96031260490417480469e-02, /* 0x3fb6f03b00000000 */ ++ 9.34767723083496093750e-02, /* 0x3fb7ee1800000000 */ ++ 9.73475575447082519531e-02, /* 0x3fb8ebc500000000 */ ++ 1.01215422153472900391e-01, /* 0x3fb9e94100000000 */ ++ 1.05080246925354003906e-01, /* 0x3fbae68a00000000 */ ++ 1.08941912651062011719e-01, /* 0x3fbbe39e00000000 */ ++ 1.12800359725952148438e-01, /* 0x3fbce07c00000000 */ ++ 1.16655409336090087891e-01, /* 0x3fbddd2100000000 */ ++ 1.20507001876831054688e-01, /* 0x3fbed98c00000000 */ ++ 1.24354958534240722656e-01, /* 0x3fbfd5ba00000000 */ ++ 1.28199219703674316406e-01, /* 0x3fc068d500000000 */ ++ 1.32039666175842285156e-01, /* 0x3fc0e6ad00000000 */ ++ 1.35876297950744628906e-01, /* 0x3fc1646500000000 */ ++ 1.39708757400512695312e-01, /* 0x3fc1e1fa00000000 */ ++ 1.43537282943725585938e-01, /* 0x3fc25f6e00000000 */ ++ 1.47361397743225097656e-01, /* 0x3fc2dcbd00000000 */ ++ 1.51181221008300781250e-01, /* 0x3fc359e800000000 */ ++ 1.54996633529663085938e-01, /* 0x3fc3d6ee00000000 */ ++ 1.58807516098022460938e-01, /* 0x3fc453ce00000000 */ ++ 1.62613749504089355469e-01, /* 0x3fc4d08700000000 */ ++ 1.66415214538574218750e-01, /* 0x3fc54d1800000000 */ ++ 1.70211911201477050781e-01, /* 0x3fc5c98100000000 */ ++ 1.74003481864929199219e-01, /* 0x3fc645bf00000000 */ ++ 1.77790164947509765625e-01, /* 0x3fc6c1d400000000 */ ++ 1.81571602821350097656e-01, /* 0x3fc73dbd00000000 */ ++ 1.85347914695739746094e-01, /* 0x3fc7b97b00000000 */ ++ 1.89118742942810058594e-01, /* 0x3fc8350b00000000 */ ++ 1.92884206771850585938e-01, /* 0x3fc8b06e00000000 */ ++ 1.96644186973571777344e-01, /* 0x3fc92ba300000000 */ ++ 2.00398445129394531250e-01, /* 0x3fc9a6a800000000 */ ++ 2.04147100448608398438e-01, /* 0x3fca217e00000000 */ ++ 2.07889914512634277344e-01, /* 0x3fca9c2300000000 */ ++ 2.11626768112182617188e-01, /* 0x3fcb169600000000 */ ++ 2.15357661247253417969e-01, /* 0x3fcb90d700000000 */ ++ 2.19082474708557128906e-01, /* 0x3fcc0ae500000000 */ ++ 2.22801089286804199219e-01, /* 0x3fcc84bf00000000 */ ++ 2.26513504981994628906e-01, /* 0x3fccfe6500000000 */ ++ 2.30219483375549316406e-01, /* 0x3fcd77d500000000 */ ++ 2.33919143676757812500e-01, /* 0x3fcdf11000000000 */ ++ 2.37612247467041015625e-01, /* 0x3fce6a1400000000 */ ++ 2.41298794746398925781e-01, /* 0x3fcee2e100000000 */ ++ 2.44978547096252441406e-01, /* 0x3fcf5b7500000000 */ ++ 2.48651623725891113281e-01, /* 0x3fcfd3d100000000 */ ++ 2.52317905426025390625e-01, /* 0x3fd025fa00000000 */ ++ 2.55977153778076171875e-01, /* 0x3fd061ee00000000 */ ++ 2.59629487991333007812e-01, /* 0x3fd09dc500000000 */ ++ 2.63274669647216796875e-01, /* 0x3fd0d97e00000000 */ ++ 2.66912937164306640625e-01, /* 0x3fd1151a00000000 */ ++ 2.70543813705444335938e-01, /* 0x3fd1509700000000 */ ++ 2.74167299270629882812e-01, /* 0x3fd18bf500000000 */ ++ 2.77783632278442382812e-01, /* 0x3fd1c73500000000 */ ++ 2.81392335891723632812e-01, /* 0x3fd2025500000000 */ ++ 2.84993648529052734375e-01, /* 0x3fd23d5600000000 */ ++ 2.88587331771850585938e-01, /* 0x3fd2783700000000 */ ++ 2.92173147201538085938e-01, /* 0x3fd2b2f700000000 */ ++ 2.95751571655273437500e-01, /* 0x3fd2ed9800000000 */ ++ 2.99322128295898437500e-01, /* 0x3fd3281800000000 */ ++ 3.02884817123413085938e-01, /* 0x3fd3627700000000 */ ++ 3.06439399719238281250e-01, /* 0x3fd39cb400000000 */ ++ 3.09986352920532226562e-01, /* 0x3fd3d6d100000000 */ ++ 3.13524961471557617188e-01, /* 0x3fd410cb00000000 */ ++ 3.17055702209472656250e-01, /* 0x3fd44aa400000000 */ ++ 3.20578098297119140625e-01, /* 0x3fd4845a00000000 */ ++ 3.24092388153076171875e-01, /* 0x3fd4bdee00000000 */ ++ 3.27598333358764648438e-01, /* 0x3fd4f75f00000000 */ ++ 3.31095933914184570312e-01, /* 0x3fd530ad00000000 */ ++ 3.34585189819335937500e-01, /* 0x3fd569d800000000 */ ++ 3.38066101074218750000e-01, /* 0x3fd5a2e000000000 */ ++ 3.41538190841674804688e-01, /* 0x3fd5dbc300000000 */ ++ 3.45002174377441406250e-01, /* 0x3fd6148400000000 */ ++ 3.48457098007202148438e-01, /* 0x3fd64d1f00000000 */ ++ 3.51903676986694335938e-01, /* 0x3fd6859700000000 */ ++ 3.55341434478759765625e-01, /* 0x3fd6bdea00000000 */ ++ 3.58770608901977539062e-01, /* 0x3fd6f61900000000 */ ++ 3.62190723419189453125e-01, /* 0x3fd72e2200000000 */ ++ 3.65602254867553710938e-01, /* 0x3fd7660700000000 */ ++ 3.69004726409912109375e-01, /* 0x3fd79dc600000000 */ ++ 3.72398376464843750000e-01, /* 0x3fd7d56000000000 */ ++ 3.75782966613769531250e-01, /* 0x3fd80cd400000000 */ ++ 3.79158496856689453125e-01, /* 0x3fd8442200000000 */ ++ 3.82525205612182617188e-01, /* 0x3fd87b4b00000000 */ ++ 3.85882616043090820312e-01, /* 0x3fd8b24d00000000 */ ++ 3.89230966567993164062e-01, /* 0x3fd8e92900000000 */ ++ 3.92570018768310546875e-01, /* 0x3fd91fde00000000 */ ++ 3.95900011062622070312e-01, /* 0x3fd9566d00000000 */ ++ 3.99220705032348632812e-01, /* 0x3fd98cd500000000 */ ++ 4.02532100677490234375e-01, /* 0x3fd9c31600000000 */ ++ 4.05834197998046875000e-01, /* 0x3fd9f93000000000 */ ++ 4.09126996994018554688e-01, /* 0x3fda2f2300000000 */ ++ 4.12410259246826171875e-01, /* 0x3fda64ee00000000 */ ++ 4.15684223175048828125e-01, /* 0x3fda9a9200000000 */ ++ 4.18948888778686523438e-01, /* 0x3fdad00f00000000 */ ++ 4.22204017639160156250e-01, /* 0x3fdb056400000000 */ ++ 4.25449609756469726562e-01, /* 0x3fdb3a9100000000 */ ++ 4.28685665130615234375e-01, /* 0x3fdb6f9600000000 */ ++ 4.31912183761596679688e-01, /* 0x3fdba47300000000 */ ++ 4.35129165649414062500e-01, /* 0x3fdbd92800000000 */ ++ 4.38336372375488281250e-01, /* 0x3fdc0db400000000 */ ++ 4.41534280776977539062e-01, /* 0x3fdc421900000000 */ ++ 4.44722414016723632812e-01, /* 0x3fdc765500000000 */ ++ 4.47900772094726562500e-01, /* 0x3fdcaa6800000000 */ ++ 4.51069593429565429688e-01, /* 0x3fdcde5300000000 */ ++ 4.54228639602661132812e-01, /* 0x3fdd121500000000 */ ++ 4.57377910614013671875e-01, /* 0x3fdd45ae00000000 */ ++ 4.60517644882202148438e-01, /* 0x3fdd791f00000000 */ ++ 4.63647603988647460938e-01, /* 0x3fddac6700000000 */ ++ 4.66767549514770507812e-01, /* 0x3fdddf8500000000 */ ++ 4.69877958297729492188e-01, /* 0x3fde127b00000000 */ ++ 4.72978591918945312500e-01, /* 0x3fde454800000000 */ ++ 4.76069211959838867188e-01, /* 0x3fde77eb00000000 */ ++ 4.79150056838989257812e-01, /* 0x3fdeaa6500000000 */ ++ 4.82221126556396484375e-01, /* 0x3fdedcb600000000 */ ++ 4.85282421112060546875e-01, /* 0x3fdf0ede00000000 */ ++ 4.88333940505981445312e-01, /* 0x3fdf40dd00000000 */ ++ 4.91375446319580078125e-01, /* 0x3fdf72b200000000 */ ++ 4.94406938552856445312e-01, /* 0x3fdfa45d00000000 */ ++ 4.97428894042968750000e-01, /* 0x3fdfd5e000000000 */ ++ 5.00440597534179687500e-01, /* 0x3fe0039c00000000 */ ++ 5.03442764282226562500e-01, /* 0x3fe01c3400000000 */ ++ 5.06434917449951171875e-01, /* 0x3fe034b700000000 */ ++ 5.09417057037353515625e-01, /* 0x3fe04d2500000000 */ ++ 5.12389183044433593750e-01, /* 0x3fe0657e00000000 */ ++ 5.15351772308349609375e-01, /* 0x3fe07dc300000000 */ ++ 5.18304347991943359375e-01, /* 0x3fe095f300000000 */ ++ 5.21246910095214843750e-01, /* 0x3fe0ae0e00000000 */ ++ 5.24179458618164062500e-01, /* 0x3fe0c61400000000 */ ++ 5.27101993560791015625e-01, /* 0x3fe0de0500000000 */ ++ 5.30014991760253906250e-01, /* 0x3fe0f5e200000000 */ ++ 5.32917976379394531250e-01, /* 0x3fe10daa00000000 */ ++ 5.35810947418212890625e-01, /* 0x3fe1255d00000000 */ ++ 5.38693904876708984375e-01, /* 0x3fe13cfb00000000 */ ++ 5.41567325592041015625e-01, /* 0x3fe1548500000000 */ ++ 5.44430732727050781250e-01, /* 0x3fe16bfa00000000 */ ++ 5.47284126281738281250e-01, /* 0x3fe1835a00000000 */ ++ 5.50127506256103515625e-01, /* 0x3fe19aa500000000 */ ++ 5.52961349487304687500e-01, /* 0x3fe1b1dc00000000 */ ++ 5.55785179138183593750e-01, /* 0x3fe1c8fe00000000 */ ++ 5.58598995208740234375e-01, /* 0x3fe1e00b00000000 */ ++ 5.61403274536132812500e-01, /* 0x3fe1f70400000000 */ ++ 5.64197540283203125000e-01, /* 0x3fe20de800000000 */ ++ 5.66981792449951171875e-01, /* 0x3fe224b700000000 */ ++ 5.69756031036376953125e-01, /* 0x3fe23b7100000000 */ ++ 5.72520732879638671875e-01, /* 0x3fe2521700000000 */ ++ 5.75275897979736328125e-01, /* 0x3fe268a900000000 */ ++ 5.78021049499511718750e-01, /* 0x3fe27f2600000000 */ ++ 5.80756187438964843750e-01, /* 0x3fe2958e00000000 */ ++ 5.83481788635253906250e-01, /* 0x3fe2abe200000000 */ ++ 5.86197376251220703125e-01, /* 0x3fe2c22100000000 */ ++ 5.88903427124023437500e-01, /* 0x3fe2d84c00000000 */ ++ 5.91599464416503906250e-01, /* 0x3fe2ee6200000000 */ ++ 5.94285964965820312500e-01, /* 0x3fe3046400000000 */ ++ 5.96962928771972656250e-01, /* 0x3fe31a5200000000 */ ++ 5.99629878997802734375e-01, /* 0x3fe3302b00000000 */ ++ 6.02287292480468750000e-01, /* 0x3fe345f000000000 */ ++ 6.04934692382812500000e-01, /* 0x3fe35ba000000000 */ ++ 6.07573032379150390625e-01, /* 0x3fe3713d00000000 */ ++ 6.10201358795166015625e-01, /* 0x3fe386c500000000 */ ++ 6.12820148468017578125e-01, /* 0x3fe39c3900000000 */ ++ 6.15428924560546875000e-01, /* 0x3fe3b19800000000 */ ++ 6.18028640747070312500e-01, /* 0x3fe3c6e400000000 */ ++ 6.20618820190429687500e-01, /* 0x3fe3dc1c00000000 */ ++ 6.23198986053466796875e-01, /* 0x3fe3f13f00000000 */ ++ 6.25770092010498046875e-01, /* 0x3fe4064f00000000 */ ++ 6.28331184387207031250e-01, /* 0x3fe41b4a00000000 */ ++ 6.30883216857910156250e-01, /* 0x3fe4303200000000 */ ++ 6.33425712585449218750e-01, /* 0x3fe4450600000000 */ ++ 6.35958671569824218750e-01, /* 0x3fe459c600000000 */ ++ 6.38482093811035156250e-01, /* 0x3fe46e7200000000 */ ++ 6.40995979309082031250e-01, /* 0x3fe4830a00000000 */ ++ 6.43500804901123046875e-01, /* 0x3fe4978f00000000 */ ++ 6.45996093750000000000e-01, /* 0x3fe4ac0000000000 */ ++ 6.48482322692871093750e-01, /* 0x3fe4c05e00000000 */ ++ 6.50959014892578125000e-01, /* 0x3fe4d4a800000000 */ ++ 6.53426170349121093750e-01, /* 0x3fe4e8de00000000 */ ++ 6.55884265899658203125e-01, /* 0x3fe4fd0100000000 */ ++ 6.58332824707031250000e-01, /* 0x3fe5111000000000 */ ++ 6.60772323608398437500e-01, /* 0x3fe5250c00000000 */ ++ 6.63202762603759765625e-01, /* 0x3fe538f500000000 */ ++ 6.65623664855957031250e-01, /* 0x3fe54cca00000000 */ ++ 6.68035984039306640625e-01, /* 0x3fe5608d00000000 */ ++ 6.70438766479492187500e-01, /* 0x3fe5743c00000000 */ ++ 6.72832489013671875000e-01, /* 0x3fe587d800000000 */ ++ 6.75216674804687500000e-01, /* 0x3fe59b6000000000 */ ++ 6.77592277526855468750e-01, /* 0x3fe5aed600000000 */ ++ 6.79958820343017578125e-01, /* 0x3fe5c23900000000 */ ++ 6.82316303253173828125e-01, /* 0x3fe5d58900000000 */ ++ 6.84664726257324218750e-01, /* 0x3fe5e8c600000000 */ ++ 6.87004089355468750000e-01, /* 0x3fe5fbf000000000 */ ++ 6.89334869384765625000e-01, /* 0x3fe60f0800000000 */ ++ 6.91656589508056640625e-01, /* 0x3fe6220d00000000 */ ++ 6.93969249725341796875e-01, /* 0x3fe634ff00000000 */ ++ 6.96272850036621093750e-01, /* 0x3fe647de00000000 */ ++ 6.98567867279052734375e-01, /* 0x3fe65aab00000000 */ ++ 7.00854301452636718750e-01, /* 0x3fe66d6600000000 */ ++ 7.03131675720214843750e-01, /* 0x3fe6800e00000000 */ ++ 7.05400466918945312500e-01, /* 0x3fe692a400000000 */ ++ 7.07660198211669921875e-01, /* 0x3fe6a52700000000 */ ++ 7.09911346435546875000e-01, /* 0x3fe6b79800000000 */ ++ 7.12153911590576171875e-01, /* 0x3fe6c9f700000000 */ ++ 7.14387893676757812500e-01, /* 0x3fe6dc4400000000 */ ++ 7.16613292694091796875e-01, /* 0x3fe6ee7f00000000 */ ++ 7.18829631805419921875e-01, /* 0x3fe700a700000000 */ ++ 7.21037864685058593750e-01, /* 0x3fe712be00000000 */ ++ 7.23237514495849609375e-01, /* 0x3fe724c300000000 */ ++ 7.25428581237792968750e-01, /* 0x3fe736b600000000 */ ++ 7.27611064910888671875e-01, /* 0x3fe7489700000000 */ ++ 7.29785442352294921875e-01, /* 0x3fe75a6700000000 */ ++ 7.31950759887695312500e-01, /* 0x3fe76c2400000000 */ ++ 7.34108448028564453125e-01, /* 0x3fe77dd100000000 */ ++ 7.36257076263427734375e-01, /* 0x3fe78f6b00000000 */ ++ 7.38397598266601562500e-01, /* 0x3fe7a0f400000000 */ ++ 7.40530014038085937500e-01, /* 0x3fe7b26c00000000 */ ++ 7.42654323577880859375e-01, /* 0x3fe7c3d300000000 */ ++ 7.44770050048828125000e-01, /* 0x3fe7d52800000000 */ ++ 7.46877670288085937500e-01, /* 0x3fe7e66c00000000 */ ++ 7.48976707458496093750e-01, /* 0x3fe7f79e00000000 */ ++ 7.51068115234375000000e-01, /* 0x3fe808c000000000 */ ++ 7.53150939941406250000e-01, /* 0x3fe819d000000000 */ ++ 7.55226135253906250000e-01, /* 0x3fe82ad000000000 */ ++ 7.57292747497558593750e-01, /* 0x3fe83bbe00000000 */ ++ 7.59351730346679687500e-01, /* 0x3fe84c9c00000000 */ ++ 7.61402606964111328125e-01, /* 0x3fe85d6900000000 */ ++ 7.63445377349853515625e-01, /* 0x3fe86e2500000000 */ ++ 7.65480041503906250000e-01, /* 0x3fe87ed000000000 */ ++ 7.67507076263427734375e-01, /* 0x3fe88f6b00000000 */ ++ 7.69526004791259765625e-01, /* 0x3fe89ff500000000 */ ++ 7.71537303924560546875e-01, /* 0x3fe8b06f00000000 */ ++ 7.73540973663330078125e-01, /* 0x3fe8c0d900000000 */ ++ 7.75536537170410156250e-01, /* 0x3fe8d13200000000 */ ++ 7.77523994445800781250e-01, /* 0x3fe8e17a00000000 */ ++ 7.79504299163818359375e-01, /* 0x3fe8f1b300000000 */ ++ 7.81476497650146484375e-01, /* 0x3fe901db00000000 */ ++ 7.83441066741943359375e-01, /* 0x3fe911f300000000 */ ++ 7.85398006439208984375e-01}; /* 0x3fe921fb00000000 */ ++ ++ static const double atan_jby256_tail[ 241] = { ++ 2.13244638182005395671e-08, /* 0x3e56e59fbd38db2c */ ++ 3.89093864761712760656e-08, /* 0x3e64e3aa54dedf96 */ ++ 4.44780900009437454576e-08, /* 0x3e67e105ab1bda88 */ ++ 1.15344768460112754160e-08, /* 0x3e48c5254d013fd0 */ ++ 3.37271051945395312705e-09, /* 0x3e2cf8ab3ad62670 */ ++ 2.40857608736109859459e-08, /* 0x3e59dca4bec80468 */ ++ 1.85853810450623807768e-08, /* 0x3e53f4b5ec98a8da */ ++ 5.14358299969225078306e-08, /* 0x3e6b9d49619d81fe */ ++ 8.85023985412952486748e-09, /* 0x3e43017887460934 */ ++ 1.59425154214358432060e-08, /* 0x3e511e3eca0b9944 */ ++ 1.95139937737755753164e-08, /* 0x3e54f3f73c5a332e */ ++ 2.64909755273544319715e-08, /* 0x3e5c71c8ae0e00a6 */ ++ 4.43388037881231070144e-08, /* 0x3e67cde0f86fbdc7 */ ++ 2.14757072421821274557e-08, /* 0x3e570f328c889c72 */ ++ 2.61049792670754218852e-08, /* 0x3e5c07ae9b994efe */ ++ 7.81439350674466302231e-09, /* 0x3e40c8021d7b1698 */ ++ 3.60125207123751024094e-08, /* 0x3e635585edb8cb22 */ ++ 6.15276238179343767917e-08, /* 0x3e70842567b30e96 */ ++ 9.54387964641184285058e-08, /* 0x3e799e811031472e */ ++ 3.02789566851502754129e-08, /* 0x3e6041821416bcee */ ++ 1.16888650949870856331e-07, /* 0x3e7f6086e4dc96f4 */ ++ 1.07580956468653338863e-08, /* 0x3e471a535c5f1b58 */ ++ 8.33454265379535427653e-08, /* 0x3e765f743fe63ca1 */ ++ 1.10790279272629526068e-07, /* 0x3e7dbd733472d014 */ ++ 1.08394277896366207424e-07, /* 0x3e7d18cc4d8b0d1d */ ++ 9.22176086126841098800e-08, /* 0x3e78c12553c8fb29 */ ++ 7.90938592199048786990e-08, /* 0x3e753b49e2e8f991 */ ++ 8.66445407164293125637e-08, /* 0x3e77422ae148c141 */ ++ 1.40839973537092438671e-08, /* 0x3e4e3ec269df56a8 */ ++ 1.19070438507307600689e-07, /* 0x3e7ff6754e7e0ac9 */ ++ 6.40451663051716197071e-08, /* 0x3e7131267b1b5aad */ ++ 1.08338682076343674522e-07, /* 0x3e7d14fa403a94bc */ ++ 3.52999550187922736222e-08, /* 0x3e62f396c089a3d8 */ ++ 1.05983273930043077202e-07, /* 0x3e7c731d78fa95bb */ ++ 1.05486124078259553339e-07, /* 0x3e7c50f385177399 */ ++ 5.82167732281776477773e-08, /* 0x3e6f41409c6f2c20 */ ++ 1.08696483983403942633e-07, /* 0x3e7d2d90c4c39ec0 */ ++ 4.47335086122377542835e-08, /* 0x3e680420696f2106 */ ++ 1.26896287162615723528e-08, /* 0x3e4b40327943a2e8 */ ++ 4.06534471589151404531e-08, /* 0x3e65d35e02f3d2a2 */ ++ 3.84504846300557026690e-08, /* 0x3e64a498288117b0 */ ++ 3.60715006404807269080e-08, /* 0x3e635da119afb324 */ ++ 6.44725903165522722801e-08, /* 0x3e714e85cdb9a908 */ ++ 3.63749249976409461305e-08, /* 0x3e638754e5547b9a */ ++ 1.03901294413833913794e-07, /* 0x3e7be40ae6ce3246 */ ++ 6.25379756302167880580e-08, /* 0x3e70c993b3bea7e7 */ ++ 6.63984302368488828029e-08, /* 0x3e71d2dd89ac3359 */ ++ 3.21844598971548278059e-08, /* 0x3e61476603332c46 */ ++ 1.16030611712765830905e-07, /* 0x3e7f25901bac55b7 */ ++ 1.17464622142347730134e-07, /* 0x3e7f881b7c826e28 */ ++ 7.54604017965808996596e-08, /* 0x3e7441996d698d20 */ ++ 1.49234929356206556899e-07, /* 0x3e8407ac521ea089 */ ++ 1.41416924523217430259e-07, /* 0x3e82fb0c6c4b1723 */ ++ 2.13308065617483489011e-07, /* 0x3e8ca135966a3e18 */ ++ 5.04230937933302320146e-08, /* 0x3e6b1218e4d646e4 */ ++ 5.45874922281655519035e-08, /* 0x3e6d4e72a350d288 */ ++ 1.51849028914786868886e-07, /* 0x3e84617e2f04c329 */ ++ 3.09004308703769273010e-08, /* 0x3e6096ec41e82650 */ ++ 9.67574548184738317664e-08, /* 0x3e79f91f25773e6e */ ++ 4.02508285529322212824e-08, /* 0x3e659c0820f1d674 */ ++ 3.01222268096861091157e-08, /* 0x3e602bf7a2df1064 */ ++ 2.36189860670079288680e-07, /* 0x3e8fb36bfc40508f */ ++ 1.14095158111080887695e-07, /* 0x3e7ea08f3f8dc892 */ ++ 7.42349089746573467487e-08, /* 0x3e73ed6254656a0e */ ++ 5.12515583196230380184e-08, /* 0x3e6b83f5e5e69c58 */ ++ 2.19290391828763918102e-07, /* 0x3e8d6ec2af768592 */ ++ 3.83263512187553886471e-08, /* 0x3e6493889a226f94 */ ++ 1.61513486284090523855e-07, /* 0x3e85ad8fa65279ba */ ++ 5.09996743535589922261e-08, /* 0x3e6b615784d45434 */ ++ 1.23694037861246766534e-07, /* 0x3e809a184368f145 */ ++ 8.23367955351123783984e-08, /* 0x3e761a2439b0d91c */ ++ 1.07591766213053694014e-07, /* 0x3e7ce1a65e39a978 */ ++ 1.42789947524631815640e-07, /* 0x3e832a39a93b6a66 */ ++ 1.32347123024711878538e-07, /* 0x3e81c3699af804e7 */ ++ 2.17626067316598149229e-08, /* 0x3e575e0f4e44ede8 */ ++ 2.34454866923044288656e-07, /* 0x3e8f77ced1a7a83b */ ++ 2.82966370261766916053e-09, /* 0x3e284e7f0cb1b500 */ ++ 2.29300919890907632975e-07, /* 0x3e8ec6b838b02dfe */ ++ 1.48428270450261284915e-07, /* 0x3e83ebf4dfbeda87 */ ++ 1.87937408574313982512e-07, /* 0x3e89397aed9cb475 */ ++ 6.13685946813334055347e-08, /* 0x3e707937bc239c54 */ ++ 1.98585022733583817493e-07, /* 0x3e8aa754553131b6 */ ++ 7.68394131623752961662e-08, /* 0x3e74a05d407c45dc */ ++ 1.28119052312436745644e-07, /* 0x3e8132231a206dd0 */ ++ 7.02119104719236502733e-08, /* 0x3e72d8ecfdd69c88 */ ++ 9.87954793820636301943e-08, /* 0x3e7a852c74218606 */ ++ 1.72176752381034986217e-07, /* 0x3e871bf2baeebb50 */ ++ 1.12877225146169704119e-08, /* 0x3e483d7db7491820 */ ++ 5.33549829555851737993e-08, /* 0x3e6ca50d92b6da14 */ ++ 2.13833275710816521345e-08, /* 0x3e56f5cde8530298 */ ++ 1.16243518048290556393e-07, /* 0x3e7f343198910740 */ ++ 6.29926408369055877943e-08, /* 0x3e70e8d241ccd80a */ ++ 6.45429039328021963791e-08, /* 0x3e71535ac619e6c8 */ ++ 8.64001922814281933403e-08, /* 0x3e77316041c36cd2 */ ++ 9.50767572202325800240e-08, /* 0x3e7985a000637d8e */ ++ 5.80851497508121135975e-08, /* 0x3e6f2f29858c0a68 */ ++ 1.82350561135024766232e-07, /* 0x3e8879847f96d909 */ ++ 1.98948680587390608655e-07, /* 0x3e8ab3d319e12e42 */ ++ 7.83548663450197659846e-08, /* 0x3e75088162dfc4c2 */ ++ 3.04374234486798594427e-08, /* 0x3e605749a1cd9d8c */ ++ 2.76135725629797411787e-08, /* 0x3e5da65c6c6b8618 */ ++ 4.32610105454203065470e-08, /* 0x3e6739bf7df1ad64 */ ++ 5.17107515324127256994e-08, /* 0x3e6bc31252aa3340 */ ++ 2.82398327875841444660e-08, /* 0x3e5e528191ad3aa8 */ ++ 1.87482469524195595399e-07, /* 0x3e8929d93df19f18 */ ++ 2.97481891662714096139e-08, /* 0x3e5ff11eb693a080 */ ++ 9.94421570843584316402e-09, /* 0x3e455ae3f145a3a0 */ ++ 1.07056210730391848428e-07, /* 0x3e7cbcd8c6c0ca82 */ ++ 6.25589580466881163081e-08, /* 0x3e70cb04d425d304 */ ++ 9.56641013869464593803e-08, /* 0x3e79adfcab5be678 */ ++ 1.88056307148355440276e-07, /* 0x3e893d90c5662508 */ ++ 8.38850689379557880950e-08, /* 0x3e768489bd35ff40 */ ++ 5.01215865527674122924e-09, /* 0x3e3586ed3da2b7e0 */ ++ 1.74166095998522089762e-07, /* 0x3e87604d2e850eee */ ++ 9.96779574395363585849e-08, /* 0x3e7ac1d12bfb53d8 */ ++ 5.98432026368321460686e-09, /* 0x3e39b3d468274740 */ ++ 1.18362922366887577169e-07, /* 0x3e7fc5d68d10e53c */ ++ 1.86086833284154215946e-07, /* 0x3e88f9e51884becb */ ++ 1.97671457251348941011e-07, /* 0x3e8a87f0869c06d1 */ ++ 1.42447160717199237159e-07, /* 0x3e831e7279f685fa */ ++ 1.05504240785546574184e-08, /* 0x3e46a8282f9719b0 */ ++ 3.13335218371639189324e-08, /* 0x3e60d2724a8a44e0 */ ++ 1.96518418901914535399e-07, /* 0x3e8a60524b11ad4e */ ++ 2.17692035039173536059e-08, /* 0x3e575fdf832750f0 */ ++ 2.15613114426529981675e-07, /* 0x3e8cf06902e4cd36 */ ++ 5.68271098300441214948e-08, /* 0x3e6e82422d4f6d10 */ ++ 1.70331455823369124256e-08, /* 0x3e524a091063e6c0 */ ++ 9.17590028095709583247e-08, /* 0x3e78a1a172dc6f38 */ ++ 2.77266304112916566247e-07, /* 0x3e929b6619f8a92d */ ++ 9.37041937614656939690e-08, /* 0x3e79274d9c1b70c8 */ ++ 1.56116346368316796511e-08, /* 0x3e50c34b1fbb7930 */ ++ 4.13967433808382727413e-08, /* 0x3e6639866c20eb50 */ ++ 1.70164749185821616276e-07, /* 0x3e86d6d0f6832e9e */ ++ 4.01708788545600086008e-07, /* 0x3e9af54def99f25e */ ++ 2.59663539226050551563e-07, /* 0x3e916cfc52a00262 */ ++ 2.22007487655027469542e-07, /* 0x3e8dcc1e83569c32 */ ++ 2.90542250809644081369e-07, /* 0x3e937f7a551ed425 */ ++ 4.67720537666628903341e-07, /* 0x3e9f6360adc98887 */ ++ 2.79799803956772554802e-07, /* 0x3e92c6ec8d35a2c1 */ ++ 2.07344552327432547723e-07, /* 0x3e8bd44df84cb036 */ ++ 2.54705698692735196368e-07, /* 0x3e9117cf826e310e */ ++ 4.26848589539548450728e-07, /* 0x3e9ca533f332cfc9 */ ++ 2.52506723633552216197e-07, /* 0x3e90f208509dbc2e */ ++ 2.14684129933849704964e-07, /* 0x3e8cd07d93c945de */ ++ 3.20134822201596505431e-07, /* 0x3e957bdfd67e6d72 */ ++ 9.93537565749855712134e-08, /* 0x3e7aab89c516c658 */ ++ 3.70792944827917252327e-08, /* 0x3e63e823b1a1b8a0 */ ++ 1.41772749369083698972e-07, /* 0x3e8307464a9d6d3c */ ++ 4.22446601490198804306e-07, /* 0x3e9c5993cd438843 */ ++ 4.11818433724801511540e-07, /* 0x3e9ba2fca02ab554 */ ++ 1.19976381502605310519e-07, /* 0x3e801a5b6983a268 */ ++ 3.43703078571520905265e-08, /* 0x3e6273d1b350efc8 */ ++ 1.66128705555453270379e-07, /* 0x3e864c238c37b0c6 */ ++ 5.00499610023283006540e-08, /* 0x3e6aded07370a300 */ ++ 1.75105139941208062123e-07, /* 0x3e878091197eb47e */ ++ 7.70807146729030327334e-08, /* 0x3e74b0f245e0dabc */ ++ 2.45918607526895836121e-07, /* 0x3e9080d9794e2eaf */ ++ 2.18359020958626199345e-07, /* 0x3e8d4ec242b60c76 */ ++ 8.44342887976445333569e-09, /* 0x3e4221d2f940caa0 */ ++ 1.07506148687888629299e-07, /* 0x3e7cdbc42b2bba5c */ ++ 5.36544954316820904572e-08, /* 0x3e6cce37bb440840 */ ++ 3.39109101518396596341e-07, /* 0x3e96c1d999cf1dd0 */ ++ 2.60098720293920613340e-08, /* 0x3e5bed8a07eb0870 */ ++ 8.42678991664621455827e-08, /* 0x3e769ed88f490e3c */ ++ 5.36972237470183633197e-08, /* 0x3e6cd41719b73ef0 */ ++ 4.28192558171921681288e-07, /* 0x3e9cbc4ac95b41b7 */ ++ 2.71535491483955143294e-07, /* 0x3e9238f1b890f5d7 */ ++ 7.84094998145075780203e-08, /* 0x3e750c4282259cc4 */ ++ 3.43880599134117431863e-07, /* 0x3e9713d2de87b3e2 */ ++ 1.32878065060366481043e-07, /* 0x3e81d5a7d2255276 */ ++ 4.18046802627967629428e-07, /* 0x3e9c0dfd48227ac1 */ ++ 2.65042411765766019424e-07, /* 0x3e91c964dab76753 */ ++ 1.70383695347518643694e-07, /* 0x3e86de56d5704496 */ ++ 1.54096497259613515678e-07, /* 0x3e84aeb71fd19968 */ ++ 2.36543402412459813461e-07, /* 0x3e8fbf91c57b1918 */ ++ 4.38416350106876736790e-07, /* 0x3e9d6bef7fbe5d9a */ ++ 3.03892161339927775731e-07, /* 0x3e9464d3dc249066 */ ++ 3.31136771605664899240e-07, /* 0x3e9638e2ec4d9073 */ ++ 6.49494294526590682218e-08, /* 0x3e716f4a7247ea7c */ ++ 4.10423429887181345747e-09, /* 0x3e31a0a740f1d440 */ ++ 1.70831640869113847224e-07, /* 0x3e86edbb0114a33c */ ++ 1.10811512657909180966e-07, /* 0x3e7dbee8bf1d513c */ ++ 3.23677724749783611964e-07, /* 0x3e95b8bdb0248f73 */ ++ 3.55662734259192678528e-07, /* 0x3e97de3d3f5eac64 */ ++ 2.30102333489738219140e-07, /* 0x3e8ee24187ae448a */ ++ 4.47429004000738629714e-07, /* 0x3e9e06c591ec5192 */ ++ 7.78167135617329598659e-08, /* 0x3e74e3861a332738 */ ++ 9.90345291908535415737e-08, /* 0x3e7a9599dcc2bfe4 */ ++ 5.85800913143113728314e-08, /* 0x3e6f732fbad43468 */ ++ 4.57859062410871843857e-07, /* 0x3e9eb9f573b727d9 */ ++ 3.67993069723390929794e-07, /* 0x3e98b212a2eb9897 */ ++ 2.90836464322977276043e-07, /* 0x3e9384884c167215 */ ++ 2.51621574250131388318e-07, /* 0x3e90e2d363020051 */ ++ 2.75789824740652815545e-07, /* 0x3e92820879fbd022 */ ++ 3.88985776250314403593e-07, /* 0x3e9a1ab9893e4b30 */ ++ 1.40214080183768019611e-07, /* 0x3e82d1b817a24478 */ ++ 3.23451432223550478373e-08, /* 0x3e615d7b8ded4878 */ ++ 9.15979180730608444470e-08, /* 0x3e78968f9db3a5e4 */ ++ 3.44371402498640470421e-07, /* 0x3e971c4171fe135f */ ++ 3.40401897215059498077e-07, /* 0x3e96d80f605d0d8c */ ++ 1.06431813453707950243e-07, /* 0x3e7c91f043691590 */ ++ 1.46204238932338846248e-07, /* 0x3e839f8a15fce2b2 */ ++ 9.94610376972039046878e-09, /* 0x3e455beda9d94b80 */ ++ 2.01711528092681771039e-07, /* 0x3e8b12c15d60949a */ ++ 2.72027977986191568296e-07, /* 0x3e924167b312bfe3 */ ++ 2.48402602511693757964e-07, /* 0x3e90ab8633070277 */ ++ 1.58480011219249621715e-07, /* 0x3e854554ebbc80ee */ ++ 3.00372828113368713281e-08, /* 0x3e60204aef5a4bb8 */ ++ 3.67816204583541976394e-07, /* 0x3e98af08c679cf2c */ ++ 2.46169793032343824291e-07, /* 0x3e90852a330ae6c8 */ ++ 1.70080468270204253247e-07, /* 0x3e86d3eb9ec32916 */ ++ 1.67806717763872914315e-07, /* 0x3e8685cb7fcbbafe */ ++ 2.67715622006907942620e-07, /* 0x3e91f751c1e0bd95 */ ++ 2.14411342550299170574e-08, /* 0x3e5705b1b0f72560 */ ++ 4.11228221283669073277e-07, /* 0x3e9b98d8d808ca92 */ ++ 3.52311752396749662260e-08, /* 0x3e62ea22c75cc980 */ ++ 3.52718000397367821054e-07, /* 0x3e97aba62bca0350 */ ++ 4.38857387992911129814e-07, /* 0x3e9d73833442278c */ ++ 3.22574606753482540743e-07, /* 0x3e95a5ca1fb18bf9 */ ++ 3.28730371182804296828e-08, /* 0x3e61a6092b6ecf28 */ ++ 7.56672470607639279700e-08, /* 0x3e744fd049aac104 */ ++ 3.26750155316369681821e-09, /* 0x3e2c114fd8df5180 */ ++ 3.21724445362095284743e-07, /* 0x3e95972f130feae5 */ ++ 1.06639427371776571151e-07, /* 0x3e7ca034a55fe198 */ ++ 3.41020788139524715063e-07, /* 0x3e96e2b149990227 */ ++ 1.00582838631232552824e-07, /* 0x3e7b00000294592c */ ++ 3.68439433859276640065e-07, /* 0x3e98b9bdc442620e */ ++ 2.20403078342388012027e-07, /* 0x3e8d94fdfabf3e4e */ ++ 1.62841467098298142534e-07, /* 0x3e85db30b145ad9a */ ++ 2.25325348296680733838e-07, /* 0x3e8e3e1eb95022b0 */ ++ 4.37462238226421614339e-07, /* 0x3e9d5b8b45442bd6 */ ++ 3.52055880555040706500e-07, /* 0x3e97a046231ecd2e */ ++ 4.75614398494781776825e-07, /* 0x3e9feafe3ef55232 */ ++ 3.60998399033215317516e-07, /* 0x3e9839e7bfd78267 */ ++ 3.79292434611513945954e-08, /* 0x3e645cf49d6fa900 */ ++ 1.29859015528549300061e-08, /* 0x3e4be3132b27f380 */ ++ 3.15927546985474913188e-07, /* 0x3e9533980bb84f9f */ ++ 2.28533679887379668031e-08, /* 0x3e5889e2ce3ba390 */ ++ 1.17222541823553133877e-07, /* 0x3e7f7778c3ad0cc8 */ ++ 1.51991208405464415857e-07, /* 0x3e846660cec4eba2 */ ++ 1.56958239325240655564e-07}; /* 0x3e85110b4611a626 */ ++ ++ /* Some constants and split constants. */ ++ ++ static double pi = 3.1415926535897932e+00, /* 0x400921fb54442d18 */ ++ piby2 = 1.5707963267948966e+00, /* 0x3ff921fb54442d18 */ ++ piby4 = 7.8539816339744831e-01, /* 0x3fe921fb54442d18 */ ++ three_piby4 = 2.3561944901923449e+00, /* 0x4002d97c7f3321d2 */ ++ pi_head = 3.1415926218032836e+00, /* 0x400921fb50000000 */ ++ pi_tail = 3.1786509547056392e-08, /* 0x3e6110b4611a6263 */ ++ piby2_head = 1.5707963267948965e+00, /* 0x3ff921fb54442d18 */ ++ piby2_tail = 6.1232339957367660e-17; /* 0x3c91a62633145c07 */ ++ ++ double u, v, vbyu, q1, q2, s, u1, vu1, u2, vu2, uu, c, r; ++ unsigned int swap_vu, index, xzero, yzero, xnan, ynan, xinf, yinf; ++ int m, xexp, yexp, diffexp; ++ ++ /* Find properties of arguments x and y. */ ++ ++ unsigned long ux, ui, aux, xneg, uy, auy, yneg; ++ ++ GET_BITS_DP64(x, ux); ++ GET_BITS_DP64(y, uy); ++ aux = ux & ~SIGNBIT_DP64; ++ auy = uy & ~SIGNBIT_DP64; ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ yexp = (int)((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ xneg = ux & SIGNBIT_DP64; ++ yneg = uy & SIGNBIT_DP64; ++ xzero = (aux == 0); ++ yzero = (auy == 0); ++ xnan = (aux > PINFBITPATT_DP64); ++ ynan = (auy > PINFBITPATT_DP64); ++ xinf = (aux == PINFBITPATT_DP64); ++ yinf = (auy == PINFBITPATT_DP64); ++ ++ diffexp = yexp - xexp; ++ ++ /* Special cases */ ++ ++ if (xnan) ++ return x + x; ++ else if (ynan) ++ return y + y; ++ else if (yzero) ++ { /* Zero y gives +-0 for positive x ++ and +-pi for negative x */ ++ if ((_LIB_VERSION == _SVID_) && xzero) ++ /* Sigh - _SVID_ defines atan2(0,0) as a domain error */ ++ return retval_errno_edom(x, y); ++ else if (xneg) ++ { ++ if (yneg) return val_with_flags(-pi,AMD_F_INEXACT); ++ else return val_with_flags(pi,AMD_F_INEXACT); ++ } ++ else return y; ++ } ++ else if (xzero) ++ { /* Zero x gives +- pi/2 ++ depending on sign of y */ ++ if (yneg) return val_with_flags(-piby2,AMD_F_INEXACT); ++ else val_with_flags(piby2,AMD_F_INEXACT); ++ } ++ ++ /* Scale up both x and y if they are both below 1/4. ++ This avoids any possible later denormalised arithmetic. */ ++ ++ if ((xexp < 1021 && yexp < 1021)) ++ { ++ scaleUpDouble1024(ux, &ux); ++ scaleUpDouble1024(uy, &uy); ++ PUT_BITS_DP64(ux, x); ++ PUT_BITS_DP64(uy, y); ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ yexp = (int)((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ diffexp = yexp - xexp; ++ } ++ ++ if (diffexp > 56) ++ { /* abs(y)/abs(x) > 2^56 => arctan(x/y) ++ is insignificant compared to piby2 */ ++ if (yneg) return val_with_flags(-piby2,AMD_F_INEXACT); ++ else return val_with_flags(piby2,AMD_F_INEXACT); ++ } ++ else if (diffexp < -28 && (!xneg)) ++ { /* x positive and dominant over y by a factor of 2^28. ++ In this case atan(y/x) is y/x to machine accuracy. */ ++ ++ if (diffexp < -1074) /* Result underflows */ ++ { ++ if (yneg) ++ return val_with_flags(-0.0,AMD_F_INEXACT | AMD_F_UNDERFLOW); ++ else ++ return val_with_flags(0.0,AMD_F_INEXACT | AMD_F_UNDERFLOW); ++ } ++ else ++ { ++ if (diffexp < -1022) ++ { ++ /* Result will likely be denormalized */ ++ y = scaleDouble_1(y, 100); ++ y /= x; ++ /* Now y is 2^100 times the true result. Scale it back down. */ ++ GET_BITS_DP64(y, uy); ++ scaleDownDouble(uy, 100, &uy); ++ PUT_BITS_DP64(uy, y); ++ if ((uy & EXPBITS_DP64) == 0) ++ return val_with_flags(y, AMD_F_INEXACT | AMD_F_UNDERFLOW); ++ else ++ return y; ++ } ++ else ++ return y / x; ++ } ++ } ++ else if (diffexp < -56 && xneg) ++ { /* abs(x)/abs(y) > 2^56 and x < 0 => arctan(y/x) ++ is insignificant compared to pi */ ++ if (yneg) return val_with_flags(-pi,AMD_F_INEXACT); ++ else return val_with_flags(pi,AMD_F_INEXACT); ++ } ++ else if (yinf && xinf) ++ { /* If abs(x) and abs(y) are both infinity ++ return +-pi/4 or +- 3pi/4 according to ++ signs. */ ++ if (xneg) ++ { ++ if (yneg) return val_with_flags(-three_piby4,AMD_F_INEXACT); ++ else return val_with_flags(three_piby4,AMD_F_INEXACT); ++ } ++ else ++ { ++ if (yneg) return val_with_flags(-piby4,AMD_F_INEXACT); ++ else return val_with_flags(piby4,AMD_F_INEXACT); ++ } ++ } ++ ++ /* General case: take absolute values of arguments */ ++ ++ u = x; v = y; ++ if (xneg) u = -x; ++ if (yneg) v = -y; ++ ++ /* Swap u and v if necessary to obtain 0 < v < u. Compute v/u. */ ++ ++ swap_vu = (u < v); ++ if (swap_vu) { uu = u; u = v; v = uu; } ++ vbyu = v/u; ++ ++ if (vbyu > 0.0625) ++ { /* General values of v/u. Use a look-up ++ table and series expansion. */ ++ ++ index = (int)(256*vbyu + 0.5); ++ q1 = atan_jby256_lead[index-16]; ++ q2 = atan_jby256_tail[index-16]; ++ c = index*1./256; ++ GET_BITS_DP64(u, ui); ++ m = (int)((ui & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ u = scaleDouble_2(u,-m); ++ v = scaleDouble_2(v,-m); ++ GET_BITS_DP64(u, ui); ++ PUT_BITS_DP64(0xfffffffff8000000 & ui, u1); /* 26 leading bits of u */ ++ u2 = u - u1; ++ ++ r = ((v-c*u1)-c*u2)/(u+c*v); ++ ++ /* Polynomial approximation to atan(r) */ ++ ++ s = r*r; ++ q2 = q2 + r - r*(s * (0.33333333333224095522 - s*(0.19999918038989143496))); ++ } ++ else if (vbyu < 1.e-8) ++ { /* v/u is small enough that atan(v/u) = v/u */ ++ q1 = 0.0; ++ q2 = vbyu; ++ } ++ else /* vbyu <= 0.0625 */ ++ { ++ /* Small values of v/u. Use a series expansion ++ computed carefully to minimise cancellation */ ++ ++ GET_BITS_DP64(u, ui); ++ PUT_BITS_DP64(0xffffffff00000000 & ui, u1); ++ GET_BITS_DP64(vbyu, ui); ++ PUT_BITS_DP64(0xffffffff00000000 & ui, vu1); ++ u2 = u - u1; ++ vu2 = vbyu - vu1; ++ ++ q1 = 0.0; ++ s = vbyu*vbyu; ++ q2 = vbyu + ++ ((((v - u1*vu1) - u2*vu1) - u*vu2)/u - ++ (vbyu*s*(0.33333333333333170500 - ++ s*(0.19999999999393223405 - ++ s*(0.14285713561807169030 - ++ s*(0.11110736283514525407 - ++ s*(0.90029810285449784439E-01))))))); ++ } ++ ++ /* Tidy-up according to which quadrant the arguments lie in */ ++ ++ if (swap_vu) {q1 = piby2_head - q1; q2 = piby2_tail - q2;} ++ if (xneg) {q1 = pi_head - q1; q2 = pi_tail - q2;} ++ q1 = q1 + q2; ++ ++ if (yneg) q1 = - q1; ++ ++ return q1; ++} ++ ++weak_alias (__atan2, atan2) +diff -urpN libc/sysdeps/x86_64/fpu/s_atan2f.c libc-amd/sysdeps/x86_64/fpu/s_atan2f.c +--- libc/sysdeps/x86_64/fpu/s_atan2f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_atan2f.c 2006-03-22 02:18:10.000000000 +0100 +@@ -0,0 +1,459 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++ ++#include <errno.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VAL_WITH_FLAGS ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_SCALEUPDOUBLE1024 ++#define USE_SCALEDOWNDOUBLE ++#include "libm_inlines_amd.h" ++#undef USE_SCALEDOWNDOUBLE ++#undef USE_SCALEUPDOUBLE1024 ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range arguments ++ (only used when _LIB_VERSION is _SVID_) */ ++static inline float retval_errno_edom(float x, float y) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)y; ++ exc.type = DOMAIN; ++ exc.name = (char *)"atan2f"; ++ exc.retval = HUGE; ++ if (!matherr(&exc)) ++ { ++ (void)fputs("atan2f: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++float __atan2f(float fy, float fx) ++{ ++ /* Array atan_jby256 contains precomputed values of atan(j/256), ++ for j = 16, 17, ..., 256. */ ++ ++ static const double atan_jby256[ 241] = { ++ 6.24188099959573430842e-02, /* 0x3faff55bb72cfde9 */ ++ 6.63088949198234745008e-02, /* 0x3fb0f99ea71d52a6 */ ++ 7.01969710718705064423e-02, /* 0x3fb1f86dbf082d58 */ ++ 7.40829225490337306415e-02, /* 0x3fb2f719318a4a9a */ ++ 7.79666338315423007588e-02, /* 0x3fb3f59f0e7c559d */ ++ 8.18479898030765457007e-02, /* 0x3fb4f3fd677292fb */ ++ 8.57268757707448092464e-02, /* 0x3fb5f2324fd2d7b2 */ ++ 8.96031774848717321724e-02, /* 0x3fb6f03bdcea4b0c */ ++ 9.34767811585894559112e-02, /* 0x3fb7ee182602f10e */ ++ 9.73475734872236708739e-02, /* 0x3fb8ebc54478fb28 */ ++ 1.01215441667466668485e-01, /* 0x3fb9e94153cfdcf1 */ ++ 1.05080273416329528224e-01, /* 0x3fbae68a71c722b8 */ ++ 1.08941956989865793015e-01, /* 0x3fbbe39ebe6f07c3 */ ++ 1.12800381201659388752e-01, /* 0x3fbce07c5c3cca32 */ ++ 1.16655435441069349478e-01, /* 0x3fbddd21701eba6e */ ++ 1.20507009691224548087e-01, /* 0x3fbed98c2190043a */ ++ 1.24354994546761424279e-01, /* 0x3fbfd5ba9aac2f6d */ ++ 1.28199281231298117811e-01, /* 0x3fc068d584212b3d */ ++ 1.32039761614638734288e-01, /* 0x3fc0e6adccf40881 */ ++ 1.35876328229701304195e-01, /* 0x3fc1646541060850 */ ++ 1.39708874289163620386e-01, /* 0x3fc1e1fafb043726 */ ++ 1.43537293701821222491e-01, /* 0x3fc25f6e171a535c */ ++ 1.47361481088651630200e-01, /* 0x3fc2dcbdb2fba1ff */ ++ 1.51181331798580037562e-01, /* 0x3fc359e8edeb99a3 */ ++ 1.54996741923940972718e-01, /* 0x3fc3d6eee8c6626c */ ++ 1.58807608315631065832e-01, /* 0x3fc453cec6092a9e */ ++ 1.62613828597948567589e-01, /* 0x3fc4d087a9da4f17 */ ++ 1.66415301183114927586e-01, /* 0x3fc54d18ba11570a */ ++ 1.70211925285474380276e-01, /* 0x3fc5c9811e3ec269 */ ++ 1.74003600935367680469e-01, /* 0x3fc645bfffb3aa73 */ ++ 1.77790228992676047071e-01, /* 0x3fc6c1d4898933d8 */ ++ 1.81571711160032150945e-01, /* 0x3fc73dbde8a7d201 */ ++ 1.85347949995694760705e-01, /* 0x3fc7b97b4bce5b02 */ ++ 1.89118848926083965578e-01, /* 0x3fc8350be398ebc7 */ ++ 1.92884312257974643856e-01, /* 0x3fc8b06ee2879c28 */ ++ 1.96644245190344985064e-01, /* 0x3fc92ba37d050271 */ ++ 2.00398553825878511514e-01, /* 0x3fc9a6a8e96c8626 */ ++ 2.04147145182116990236e-01, /* 0x3fca217e601081a5 */ ++ 2.07889927202262986272e-01, /* 0x3fca9c231b403279 */ ++ 2.11626808765629753628e-01, /* 0x3fcb1696574d780b */ ++ 2.15357699697738047551e-01, /* 0x3fcb90d7529260a2 */ ++ 2.19082510780057748701e-01, /* 0x3fcc0ae54d768466 */ ++ 2.22801153759394493514e-01, /* 0x3fcc84bf8a742e6d */ ++ 2.26513541356919617664e-01, /* 0x3fccfe654e1d5395 */ ++ 2.30219587276843717927e-01, /* 0x3fcd77d5df205736 */ ++ 2.33919206214733416127e-01, /* 0x3fcdf110864c9d9d */ ++ 2.37612313865471241892e-01, /* 0x3fce6a148e96ec4d */ ++ 2.41298826930858800743e-01, /* 0x3fcee2e1451d980c */ ++ 2.44978663126864143473e-01, /* 0x3fcf5b75f92c80dd */ ++ 2.48651741190513253521e-01, /* 0x3fcfd3d1fc40dbe4 */ ++ 2.52317980886427151166e-01, /* 0x3fd025fa510665b5 */ ++ 2.55977303013005474952e-01, /* 0x3fd061eea03d6290 */ ++ 2.59629629408257511791e-01, /* 0x3fd09dc597d86362 */ ++ 2.63274882955282396590e-01, /* 0x3fd0d97ee509acb3 */ ++ 2.66912987587400396539e-01, /* 0x3fd1151a362431c9 */ ++ 2.70543868292936529052e-01, /* 0x3fd150973a9ce546 */ ++ 2.74167451119658789338e-01, /* 0x3fd18bf5a30bf178 */ ++ 2.77783663178873208022e-01, /* 0x3fd1c735212dd883 */ ++ 2.81392432649178403370e-01, /* 0x3fd2025567e47c95 */ ++ 2.84993688779881237938e-01, /* 0x3fd23d562b381041 */ ++ 2.88587361894077354396e-01, /* 0x3fd278372057ef45 */ ++ 2.92173383391398755471e-01, /* 0x3fd2b2f7fd9b5fe2 */ ++ 2.95751685750431536626e-01, /* 0x3fd2ed987a823cfe */ ++ 2.99322202530807379706e-01, /* 0x3fd328184fb58951 */ ++ 3.02884868374971361060e-01, /* 0x3fd362773707ebcb */ ++ 3.06439619009630070945e-01, /* 0x3fd39cb4eb76157b */ ++ 3.09986391246883430384e-01, /* 0x3fd3d6d129271134 */ ++ 3.13525122985043869228e-01, /* 0x3fd410cbad6c7d32 */ ++ 3.17055753209146973237e-01, /* 0x3fd44aa436c2af09 */ ++ 3.20578221991156986359e-01, /* 0x3fd4845a84d0c21b */ ++ 3.24092470489871664618e-01, /* 0x3fd4bdee586890e6 */ ++ 3.27598440950530811477e-01, /* 0x3fd4f75f73869978 */ ++ 3.31096076704132047386e-01, /* 0x3fd530ad9951cd49 */ ++ 3.34585322166458920545e-01, /* 0x3fd569d88e1b4cd7 */ ++ 3.38066122836825466713e-01, /* 0x3fd5a2e0175e0f4e */ ++ 3.41538425296541714449e-01, /* 0x3fd5dbc3fbbe768d */ ++ 3.45002177207105076295e-01, /* 0x3fd614840309cfe1 */ ++ 3.48457327308122011278e-01, /* 0x3fd64d1ff635c1c5 */ ++ 3.51903825414964732676e-01, /* 0x3fd685979f5fa6fd */ ++ 3.55341622416168290144e-01, /* 0x3fd6bdeac9cbd76c */ ++ 3.58770670270572189509e-01, /* 0x3fd6f61941e4def0 */ ++ 3.62190922004212156882e-01, /* 0x3fd72e22d53aa2a9 */ ++ 3.65602331706966821034e-01, /* 0x3fd7660752817501 */ ++ 3.69004854528964421068e-01, /* 0x3fd79dc6899118d1 */ ++ 3.72398446676754202311e-01, /* 0x3fd7d5604b63b3f7 */ ++ 3.75783065409248884237e-01, /* 0x3fd80cd46a14b1d0 */ ++ 3.79158669033441808605e-01, /* 0x3fd84422b8df95d7 */ ++ 3.82525216899905096124e-01, /* 0x3fd87b4b0c1ebedb */ ++ 3.85882669398073752109e-01, /* 0x3fd8b24d394a1b25 */ ++ 3.89230987951320717144e-01, /* 0x3fd8e92916f5cde8 */ ++ 3.92570135011828580396e-01, /* 0x3fd91fde7cd0c662 */ ++ 3.95900074055262896078e-01, /* 0x3fd9566d43a34907 */ ++ 3.99220769575252543149e-01, /* 0x3fd98cd5454d6b18 */ ++ 4.02532187077682512832e-01, /* 0x3fd9c3165cc58107 */ ++ 4.05834293074804064450e-01, /* 0x3fd9f93066168001 */ ++ 4.09127055079168300278e-01, /* 0x3fda2f233e5e530b */ ++ 4.12410441597387267265e-01, /* 0x3fda64eec3cc23fc */ ++ 4.15684422123729413467e-01, /* 0x3fda9a92d59e98cf */ ++ 4.18948967133552840902e-01, /* 0x3fdad00f5422058b */ ++ 4.22204048076583571270e-01, /* 0x3fdb056420ae9343 */ ++ 4.25449637370042266227e-01, /* 0x3fdb3a911da65c6c */ ++ 4.28685708391625730496e-01, /* 0x3fdb6f962e737efb */ ++ 4.31912235472348193799e-01, /* 0x3fdba473378624a5 */ ++ 4.35129193889246812521e-01, /* 0x3fdbd9281e528191 */ ++ 4.38336559857957774877e-01, /* 0x3fdc0db4c94ec9ef */ ++ 4.41534310525166673322e-01, /* 0x3fdc42191ff11eb6 */ ++ 4.44722423960939305942e-01, /* 0x3fdc76550aad71f8 */ ++ 4.47900879150937292206e-01, /* 0x3fdcaa6872f3631b */ ++ 4.51069655988523443568e-01, /* 0x3fdcde53432c1350 */ ++ 4.54228735266762495559e-01, /* 0x3fdd121566b7f2ad */ ++ 4.57378098670320809571e-01, /* 0x3fdd45aec9ec862b */ ++ 4.60517728767271039558e-01, /* 0x3fdd791f5a1226f4 */ ++ 4.63647609000806093515e-01, /* 0x3fddac670561bb4f */ ++ 4.66767723680866497560e-01, /* 0x3fdddf85bb026974 */ ++ 4.69878057975686880265e-01, /* 0x3fde127b6b0744af */ ++ 4.72978597903265574054e-01, /* 0x3fde4548066cf51a */ ++ 4.76069330322761219421e-01, /* 0x3fde77eb7f175a34 */ ++ 4.79150242925822533735e-01, /* 0x3fdeaa65c7cf28c4 */ ++ 4.82221324227853687105e-01, /* 0x3fdedcb6d43f8434 */ ++ 4.85282563559221225002e-01, /* 0x3fdf0ede98f393cf */ ++ 4.88333951056405479729e-01, /* 0x3fdf40dd0b541417 */ ++ 4.91375477653101910835e-01, /* 0x3fdf72b221a4e495 */ ++ 4.94407135071275316562e-01, /* 0x3fdfa45dd3029258 */ ++ 4.97428915812172245392e-01, /* 0x3fdfd5e0175fdf83 */ ++ 5.00440813147294050189e-01, /* 0x3fe0039c73c1a40b */ ++ 5.03442821109336358099e-01, /* 0x3fe01c341e82422d */ ++ 5.06434934483096732549e-01, /* 0x3fe034b709250488 */ ++ 5.09417148796356245022e-01, /* 0x3fe04d25314342e5 */ ++ 5.12389460310737621107e-01, /* 0x3fe0657e94db30cf */ ++ 5.15351866012543347040e-01, /* 0x3fe07dc3324e9b38 */ ++ 5.18304363603577900044e-01, /* 0x3fe095f30861a58f */ ++ 5.21246951491958210312e-01, /* 0x3fe0ae0e1639866c */ ++ 5.24179628782913242802e-01, /* 0x3fe0c6145b5b43da */ ++ 5.27102395269579471204e-01, /* 0x3fe0de05d7aa6f7c */ ++ 5.30015251423793132268e-01, /* 0x3fe0f5e28b67e295 */ ++ 5.32918198386882147055e-01, /* 0x3fe10daa77307a0d */ ++ 5.35811237960463593311e-01, /* 0x3fe1255d9bfbd2a8 */ ++ 5.38694372597246617929e-01, /* 0x3fe13cfbfb1b056e */ ++ 5.41567605391844897333e-01, /* 0x3fe1548596376469 */ ++ 5.44430940071603086672e-01, /* 0x3fe16bfa6f5137e1 */ ++ 5.47284380987436924748e-01, /* 0x3fe1835a88be7c13 */ ++ 5.50127933104692989907e-01, /* 0x3fe19aa5e5299f99 */ ++ 5.52961601994028217888e-01, /* 0x3fe1b1dc87904284 */ ++ 5.55785393822313511514e-01, /* 0x3fe1c8fe7341f64f */ ++ 5.58599315343562330405e-01, /* 0x3fe1e00babdefeb3 */ ++ 5.61403373889889367732e-01, /* 0x3fe1f7043557138a */ ++ 5.64197577362497537656e-01, /* 0x3fe20de813e823b1 */ ++ 5.66981934222700489912e-01, /* 0x3fe224b74c1d192a */ ++ 5.69756453482978431069e-01, /* 0x3fe23b71e2cc9e6a */ ++ 5.72521144698072359525e-01, /* 0x3fe25217dd17e501 */ ++ 5.75276017956117824426e-01, /* 0x3fe268a940696da6 */ ++ 5.78021083869819540801e-01, /* 0x3fe27f261273d1b3 */ ++ 5.80756353567670302596e-01, /* 0x3fe2958e59308e30 */ ++ 5.83481838685214859730e-01, /* 0x3fe2abe21aded073 */ ++ 5.86197551356360535557e-01, /* 0x3fe2c2215e024465 */ ++ 5.88903504204738026395e-01, /* 0x3fe2d84c2961e48b */ ++ 5.91599710335111383941e-01, /* 0x3fe2ee628406cbca */ ++ 5.94286183324841177367e-01, /* 0x3fe30464753b090a */ ++ 5.96962937215401501234e-01, /* 0x3fe31a52048874be */ ++ 5.99629986503951384336e-01, /* 0x3fe3302b39b78856 */ ++ 6.02287346134964152178e-01, /* 0x3fe345f01cce37bb */ ++ 6.04935031491913965951e-01, /* 0x3fe35ba0b60eccce */ ++ 6.07573058389022313541e-01, /* 0x3fe3713d0df6c503 */ ++ 6.10201443063065118722e-01, /* 0x3fe386c52d3db11e */ ++ 6.12820202165241245673e-01, /* 0x3fe39c391cd41719 */ ++ 6.15429352753104952356e-01, /* 0x3fe3b198e5e2564a */ ++ 6.18028912282561737612e-01, /* 0x3fe3c6e491c78dc4 */ ++ 6.20618898599929469384e-01, /* 0x3fe3dc1c2a188504 */ ++ 6.23199329934065904268e-01, /* 0x3fe3f13fb89e96f4 */ ++ 6.25770224888563042498e-01, /* 0x3fe4064f47569f48 */ ++ 6.28331602434009650615e-01, /* 0x3fe41b4ae06fea41 */ ++ 6.30883481900321840818e-01, /* 0x3fe430328e4b26d5 */ ++ 6.33425882969144482537e-01, /* 0x3fe445065b795b55 */ ++ 6.35958825666321447834e-01, /* 0x3fe459c652badc7f */ ++ 6.38482330354437466191e-01, /* 0x3fe46e727efe4715 */ ++ 6.40996417725432032775e-01, /* 0x3fe4830aeb5f7bfd */ ++ 6.43501108793284370968e-01, /* 0x3fe4978fa3269ee1 */ ++ 6.45996424886771558604e-01, /* 0x3fe4ac00b1c71762 */ ++ 6.48482387642300484032e-01, /* 0x3fe4c05e22de94e4 */ ++ 6.50959018996812410762e-01, /* 0x3fe4d4a8023414e8 */ ++ 6.53426341180761927063e-01, /* 0x3fe4e8de5bb6ec04 */ ++ 6.55884376711170835605e-01, /* 0x3fe4fd013b7dd17e */ ++ 6.58333148384755983962e-01, /* 0x3fe51110adc5ed81 */ ++ 6.60772679271132590273e-01, /* 0x3fe5250cbef1e9fa */ ++ 6.63202992706093175102e-01, /* 0x3fe538f57b89061e */ ++ 6.65624112284960989250e-01, /* 0x3fe54ccaf0362c8f */ ++ 6.68036061856020157990e-01, /* 0x3fe5608d29c70c34 */ ++ 6.70438865514021320458e-01, /* 0x3fe5743c352b33b9 */ ++ 6.72832547593763097282e-01, /* 0x3fe587d81f732fba */ ++ 6.75217132663749830535e-01, /* 0x3fe59b60f5cfab9d */ ++ 6.77592645519925151909e-01, /* 0x3fe5aed6c5909517 */ ++ 6.79959111179481823228e-01, /* 0x3fe5c2399c244260 */ ++ 6.82316554874748071313e-01, /* 0x3fe5d58987169b18 */ ++ 6.84665002047148862907e-01, /* 0x3fe5e8c6941043cf */ ++ 6.87004478341244895212e-01, /* 0x3fe5fbf0d0d5cc49 */ ++ 6.89335009598845749323e-01, /* 0x3fe60f084b46e05e */ ++ 6.91656621853199760075e-01, /* 0x3fe6220d115d7b8d */ ++ 6.93969341323259825138e-01, /* 0x3fe634ff312d1f3b */ ++ 6.96273194408023488045e-01, /* 0x3fe647deb8e20b8f */ ++ 6.98568207680949848637e-01, /* 0x3fe65aabb6c07b02 */ ++ 7.00854407884450081312e-01, /* 0x3fe66d663923e086 */ ++ 7.03131821924453670469e-01, /* 0x3fe6800e4e7e2857 */ ++ 7.05400476865049030906e-01, /* 0x3fe692a40556fb6a */ ++ 7.07660399923197958039e-01, /* 0x3fe6a5276c4b0575 */ ++ 7.09911618463524796141e-01, /* 0x3fe6b798920b3d98 */ ++ 7.12154159993178659249e-01, /* 0x3fe6c9f7855c3198 */ ++ 7.14388052156768926793e-01, /* 0x3fe6dc44551553ae */ ++ 7.16613322731374569052e-01, /* 0x3fe6ee7f10204aef */ ++ 7.18829999621624415873e-01, /* 0x3fe700a7c5784633 */ ++ 7.21038110854851588272e-01, /* 0x3fe712be84295198 */ ++ 7.23237684576317874097e-01, /* 0x3fe724c35b4fae7b */ ++ 7.25428749044510712274e-01, /* 0x3fe736b65a172dff */ ++ 7.27611332626510676214e-01, /* 0x3fe748978fba8e0f */ ++ 7.29785463793429123314e-01, /* 0x3fe75a670b82d8d8 */ ++ 7.31951171115916565668e-01, /* 0x3fe76c24dcc6c6c0 */ ++ 7.34108483259739652560e-01, /* 0x3fe77dd112ea22c7 */ ++ 7.36257428981428097003e-01, /* 0x3fe78f6bbd5d315e */ ++ 7.38398037123989547936e-01, /* 0x3fe7a0f4eb9c19a2 */ ++ 7.40530336612692630105e-01, /* 0x3fe7b26cad2e50fd */ ++ 7.42654356450917929600e-01, /* 0x3fe7c3d311a6092b */ ++ 7.44770125716075148681e-01, /* 0x3fe7d528289fa093 */ ++ 7.46877673555587429099e-01, /* 0x3fe7e66c01c114fd */ ++ 7.48977029182941400620e-01, /* 0x3fe7f79eacb97898 */ ++ 7.51068221873802288613e-01, /* 0x3fe808c03940694a */ ++ 7.53151280962194302759e-01, /* 0x3fe819d0b7158a4c */ ++ 7.55226235836744863583e-01, /* 0x3fe82ad036000005 */ ++ 7.57293115936992444759e-01, /* 0x3fe83bbec5cdee22 */ ++ 7.59351950749757920178e-01, /* 0x3fe84c9c7653f7ea */ ++ 7.61402769805578416573e-01, /* 0x3fe85d69576cc2c5 */ ++ 7.63445602675201784315e-01, /* 0x3fe86e2578f87ae5 */ ++ 7.65480478966144461950e-01, /* 0x3fe87ed0eadc5a2a */ ++ 7.67507428319308182552e-01, /* 0x3fe88f6bbd023118 */ ++ 7.69526480405658186434e-01, /* 0x3fe89ff5ff57f1f7 */ ++ 7.71537664922959498526e-01, /* 0x3fe8b06fc1cf3dfe */ ++ 7.73541011592573490852e-01, /* 0x3fe8c0d9145cf49d */ ++ 7.75536550156311621507e-01, /* 0x3fe8d13206f8c4ca */ ++ 7.77524310373347682379e-01, /* 0x3fe8e17aa99cc05d */ ++ 7.79504322017186335181e-01, /* 0x3fe8f1b30c44f167 */ ++ 7.81476614872688268854e-01, /* 0x3fe901db3eeef187 */ ++ 7.83441218733151756304e-01, /* 0x3fe911f35199833b */ ++ 7.85398163397448278999e-01}; /* 0x3fe921fb54442d18 */ ++ ++ /* Some constants. */ ++ ++ static double pi = 3.1415926535897932e+00, /* 0x400921fb54442d18 */ ++ piby2 = 1.5707963267948966e+00, /* 0x3ff921fb54442d18 */ ++ piby4 = 7.8539816339744831e-01, /* 0x3fe921fb54442d18 */ ++ three_piby4 = 2.3561944901923449e+00; /* 0x4002d97c7f3321d2 */ ++ ++ double u, v, vbyu, q, s, uu, r; ++ unsigned int swap_vu, index, xzero, yzero, xnan, ynan, xinf, yinf; ++ int xexp, yexp, diffexp; ++ ++ double x = fx; ++ double y = fy; ++ ++ /* Find properties of arguments x and y. */ ++ ++ unsigned long ux, aux, xneg, uy, auy, yneg; ++ ++ GET_BITS_DP64(x, ux); ++ GET_BITS_DP64(y, uy); ++ aux = ux & ~SIGNBIT_DP64; ++ auy = uy & ~SIGNBIT_DP64; ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ yexp = (int)((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ xneg = ux & SIGNBIT_DP64; ++ yneg = uy & SIGNBIT_DP64; ++ xzero = (aux == 0); ++ yzero = (auy == 0); ++ xnan = (aux > PINFBITPATT_DP64); ++ ynan = (auy > PINFBITPATT_DP64); ++ xinf = (aux == PINFBITPATT_DP64); ++ yinf = (auy == PINFBITPATT_DP64); ++ ++ diffexp = yexp - xexp; ++ ++ /* Special cases */ ++ ++ if (xnan) ++ return x + x; ++ else if (ynan) ++ return y + y; ++ else if (yzero) ++ { /* Zero y gives +-0 for positive x ++ and +-pi for negative x */ ++ if ((_LIB_VERSION == _SVID_) && xzero) ++ /* Sigh - _SVID_ defines atan2(0,0) as a domain error */ ++ return retval_errno_edom(x, y); ++ else if (xneg) ++ { ++ if (yneg) return val_with_flags(-pi,AMD_F_INEXACT); ++ else return val_with_flags(pi,AMD_F_INEXACT); ++ } ++ else return y; ++ } ++ else if (xzero) ++ { /* Zero x gives +- pi/2 ++ depending on sign of y */ ++ if (yneg) return val_with_flags(-piby2,AMD_F_INEXACT); ++ else val_with_flags(piby2,AMD_F_INEXACT); ++ } ++ ++ if (diffexp > 26) ++ { /* abs(y)/abs(x) > 2^26 => arctan(x/y) ++ is insignificant compared to piby2 */ ++ if (yneg) return val_with_flags(-piby2,AMD_F_INEXACT); ++ else return val_with_flags(piby2,AMD_F_INEXACT); ++ } ++ else if (diffexp < -13 && (!xneg)) ++ { /* x positive and dominant over y by a factor of 2^13. ++ In this case atan(y/x) is y/x to machine accuracy. */ ++ ++ if (diffexp < -150) /* Result underflows */ ++ { ++ if (yneg) ++ return val_with_flags(-0.0,AMD_F_INEXACT | AMD_F_UNDERFLOW); ++ else ++ return val_with_flags(0.0,AMD_F_INEXACT | AMD_F_UNDERFLOW); ++ } ++ else ++ { ++ if (diffexp < -126) ++ { ++ /* Result will likely be denormalized */ ++ y = scaleDouble_1(y, 100); ++ y /= x; ++ /* Now y is 2^100 times the true result. Scale it back down. */ ++ GET_BITS_DP64(y, uy); ++ scaleDownDouble(uy, 100, &uy); ++ PUT_BITS_DP64(uy, y); ++ if ((uy & EXPBITS_DP64) == 0) ++ return val_with_flags(y, AMD_F_INEXACT | AMD_F_UNDERFLOW); ++ else ++ return y; ++ } ++ else ++ return y / x; ++ } ++ } ++ else if (diffexp < -26 && xneg) ++ { /* abs(x)/abs(y) > 2^56 and x < 0 => arctan(y/x) ++ is insignificant compared to pi */ ++ if (yneg) return val_with_flags(-pi,AMD_F_INEXACT); ++ else return val_with_flags(pi,AMD_F_INEXACT); ++ } ++ else if (yinf && xinf) ++ { /* If abs(x) and abs(y) are both infinity ++ return +-pi/4 or +- 3pi/4 according to ++ signs. */ ++ if (xneg) ++ { ++ if (yneg) return val_with_flags(-three_piby4,AMD_F_INEXACT); ++ else return val_with_flags(three_piby4,AMD_F_INEXACT); ++ } ++ else ++ { ++ if (yneg) return val_with_flags(-piby4,AMD_F_INEXACT); ++ else return val_with_flags(piby4,AMD_F_INEXACT); ++ } ++ } ++ ++ /* General case: take absolute values of arguments */ ++ ++ u = x; v = y; ++ if (xneg) u = -x; ++ if (yneg) v = -y; ++ ++ /* Swap u and v if necessary to obtain 0 < v < u. Compute v/u. */ ++ ++ swap_vu = (u < v); ++ if (swap_vu) { uu = u; u = v; v = uu; } ++ vbyu = v/u; ++ ++ if (vbyu > 0.0625) ++ { /* General values of v/u. Use a look-up ++ table and series expansion. */ ++ ++ index = (int)(256*vbyu + 0.5); ++ r = (256*v-index*u)/(256*u+index*v); ++ ++ /* Polynomial approximation to atan(vbyu) */ ++ ++ s = r*r; ++ q = atan_jby256[index-16] + r - r*s*0.33333333333224095522; ++ } ++ else if (vbyu < 1.e-4) ++ { /* v/u is small enough that atan(v/u) = v/u */ ++ q = vbyu; ++ } ++ else /* vbyu <= 0.0625 */ ++ { ++ /* Small values of v/u. Use a series expansion */ ++ ++ s = vbyu*vbyu; ++ q = vbyu - ++ vbyu*s*(0.33333333333333170500 - ++ s*(0.19999999999393223405 - ++ s*0.14285713561807169030)); ++ } ++ ++ /* Tidy-up according to which quadrant the arguments lie in */ ++ ++ if (swap_vu) {q = piby2 - q;} ++ if (xneg) {q = pi - q;} ++ if (yneg) q = - q; ++ return q; ++} ++ ++weak_alias (__atan2f, atan2f) +diff -urpN libc/sysdeps/x86_64/fpu/s_atan.c libc-amd/sysdeps/x86_64/fpu/s_atan.c +--- libc/sysdeps/x86_64/fpu/s_atan.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_atan.c 2006-03-22 02:19:20.000000000 +0100 +@@ -0,0 +1,146 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VAL_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#define USE_HANDLE_ERROR ++#include "libm_inlines_amd.h" ++#undef USE_VAL_WITH_FLAGS ++#undef USE_NAN_WITH_FLAGS ++#undef USE_HANDLE_ERROR ++ ++/* Deal with errno for out-of-range argument */ ++static inline double retval_errno_edom(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.name = (char *)"atan"; ++ exc.type = DOMAIN; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = nan_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++ (void)fputs("atan: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++ ++double __atan (double x) ++{ ++ ++ /* Some constants and split constants. */ ++ ++ static double piby2 = 1.5707963267948966e+00; /* 0x3ff921fb54442d18 */ ++ double chi, clo, v, s, q, z; ++ ++ /* Find properties of argument x. */ ++ ++ unsigned long ux, aux, xneg; ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ xneg = (ux != aux); ++ ++ if (xneg) v = -x; ++ else v = x; ++ ++ /* if |x| less than 1.490116119385e-8, then atan(x) = x */ ++ if (aux < 0x3E50000000000000) ++ { ++ if (aux == 0) /* if x=0, then result is precise */ ++ return x; ++ else ++ return val_with_flags(x, AMD_F_INEXACT); ++ } ++ ++ /* Argument reduction to range [-7/16,7/16] */ ++ ++ if (aux > 0x4003800000000000) /* v > 39./16. */ ++ { ++ ++ if (aux > PINFBITPATT_DP64) ++ { ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it's a signalling NaN */ ++ } ++ else if (aux > 0x4370000000000000) ++ { /* abs(x) > 2^56 => arctan(1/x) is ++ insignificant compared to piby2 */ ++ if (xneg) ++ return val_with_flags(-piby2, AMD_F_INEXACT); ++ else ++ return val_with_flags(piby2, AMD_F_INEXACT); ++ } ++ ++ x = -1.0/v; ++ /* (chi + clo) = arctan(infinity) */ ++ chi = 1.57079632679489655800e+00; /* 0x3ff921fb54442d18 */ ++ clo = 6.12323399573676480327e-17; /* 0x3c91a62633145c06 */ ++ } ++ else if (aux > 0x3ff3000000000000) /* 39./16. > v > 19./16. */ ++ { ++ x = (v-1.5)/(1.0+1.5*v); ++ /* (chi + clo) = arctan(1.5) */ ++ chi = 9.82793723247329054082e-01; /* 0x3fef730bd281f69b */ ++ clo = 1.39033110312309953701e-17; /* 0x3c7007887af0cbbc */ ++ } ++ else if (aux > 0x3fe6000000000000) /* 19./16. > v > 11./16. */ ++ { ++ x = (v-1.0)/(1.0+v); ++ /* (chi + clo) = arctan(1.) */ ++ chi = 7.85398163397448278999e-01; /* 0x3fe921fb54442d18 */ ++ clo = 3.06161699786838240164e-17; /* 0x3c81a62633145c06 */ ++ } ++ else if (aux > 0x3fdc000000000000) /* 11./16. > v > 7./16. */ ++ { ++ x = (2.0*v-1.0)/(2.0+v); ++ /* (chi + clo) = arctan(0.5) */ ++ chi = 4.63647609000806093515e-01; /* 0x3fddac670561bb4f */ ++ clo = 2.26987774529616809294e-17; /* 0x3c7a2b7f222f65e0 */ ++ } ++ else /* v < 7./16. */ ++ { ++ x = v; ++ chi = 0.0; ++ clo = 0.0; ++ } ++ ++ /* Core approximation: Remez(4,4) on [-7/16,7/16] */ ++ ++ s = x*x; ++ q = x*s* ++ (0.268297920532545909e0 + ++ (0.447677206805497472e0 + ++ (0.220638780716667420e0 + ++ (0.304455919504853031e-1 + ++ 0.142316903342317766e-3*s)*s)*s)*s)/ ++ (0.804893761597637733e0 + ++ (0.182596787737507063e1 + ++ (0.141254259931958921e1 + ++ (0.424602594203847109e0 + ++ 0.389525873944742195e-1*s)*s)*s)*s); ++ ++ z = chi - ((q - clo) - x); ++ ++ if (xneg) z = -z; ++ return z; ++} ++ ++weak_alias (__atan, atan) +diff -urpN libc/sysdeps/x86_64/fpu/s_atanf.c libc-amd/sysdeps/x86_64/fpu/s_atanf.c +--- libc/sysdeps/x86_64/fpu/s_atanf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_atanf.c 2006-03-22 02:32:58.000000000 +0100 +@@ -0,0 +1,143 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VALF_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#define USE_HANDLE_ERRORF ++#include "libm_inlines_amd.h" ++#undef USE_VALF_WITH_FLAGS ++#undef USE_NAN_WITH_FLAGS ++#undef USE_HANDLE_ERRORF ++ ++/* Deal with errno for out-of-range argument */ ++static inline float retval_errno_edom(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (float)x; ++ exc.arg2 = (float)x; ++ exc.name = (char *)"atanf"; ++ exc.type = DOMAIN; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = nan_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++ (void)fputs("atanf: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++ ++float __atanf (float fx) ++{ ++ ++ /* Some constants and split constants. */ ++ ++ static double piby2 = 1.5707963267948966e+00; /* 0x3ff921fb54442d18 */ ++ ++ double c, v, s, q, z; ++ unsigned int xnan; ++ ++ double x = fx; ++ ++ /* Find properties of argument fx. */ ++ ++ unsigned long ux, aux, xneg; ++ ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ xneg = ux & SIGNBIT_DP64; ++ ++ if (aux < 0x3ec0000000000000) /* v < 19073486328125e-06 */ ++ { ++ if (aux == 0) /* if x=0, then result is precise */ ++ return fx; ++ else ++ return valf_with_flags(fx, AMD_F_INEXACT); ++ } ++ ++ v = x; ++ if (xneg) v = -x; ++ ++ /* Argument reduction to range [-7/16,7/16] */ ++ ++ if (aux < 0x3fdc000000000000) /* v < 7./16. */ ++ { ++ x = v; ++ c = 0.0; ++ } ++ else if (aux < 0x3fe6000000000000) /* v < 11./16. */ ++ { ++ x = (2.0*v-1.0)/(2.0+v); ++ /* c = arctan(0.5) */ ++ c = 4.63647609000806093515e-01; /* 0x3fddac670561bb4f */ ++ } ++ else if (aux < 0x3ff3000000000000) /* v < 19./16. */ ++ { ++ x = (v-1.0)/(1.0+v); ++ /* c = arctan(1.) */ ++ c = 7.85398163397448278999e-01; /* 0x3fe921fb54442d18 */ ++ } ++ else if (aux < 0x4003800000000000) /* v < 39./16. */ ++ { ++ x = (v-1.5)/(1.0+1.5*v); ++ /* c = arctan(1.5) */ ++ c = 9.82793723247329054082e-01; /* 0x3fef730bd281f69b */ ++ } ++ else ++ { ++ ++ xnan = (aux > PINFBITPATT_DP64); ++ ++ if (xnan) ++ { ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it's a signalling NaN */ ++ } ++ else if (aux > 0x4190000000000000) ++ { /* abs(x) > 2^26 => arctan(1/x) is ++ insignificant compared to piby2 */ ++ if (xneg) ++ return valf_with_flags((float)-piby2, AMD_F_INEXACT); ++ else ++ return valf_with_flags((float)piby2, AMD_F_INEXACT); ++ } ++ ++ x = -1.0/v; ++ /* c = arctan(infinity) */ ++ c = 1.57079632679489655800e+00; /* 0x3ff921fb54442d18 */ ++ } ++ ++ /* Core approximation: Remez(2,2) on [-7/16,7/16] */ ++ ++ s = x*x; ++ q = x*s* ++ (0.296528598819239217902158651186e0 + ++ (0.192324546402108583211697690500e0 + ++ 0.470677934286149214138357545549e-2*s)*s)/ ++ (0.889585796862432286486651434570e0 + ++ (0.111072499995399550138837673349e1 + ++ 0.299309699959659728404442796915e0*s)*s); ++ ++ z = c - (q - x); ++ ++ if (xneg) z = -z; ++ return (float)z; ++} ++ ++weak_alias (__atanf, atanf) +diff -urpN libc/sysdeps/x86_64/fpu/s_ceil.c libc-amd/sysdeps/x86_64/fpu/s_ceil.c +--- libc/sysdeps/x86_64/fpu/s_ceil.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_ceil.c 2006-03-22 03:41:02.000000000 +0100 +@@ -0,0 +1,61 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++double __ceil(double x) ++{ ++ double r; ++ long rexp, xneg; ++ unsigned long ux, ax, ur, mask; ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ xneg = (ux != ax); ++ ++ if (ax >= 0x4340000000000000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^53 */ ++ if (ax > 0x7ff0000000000000) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ return x; ++ } ++ else if (ax < 0x3ff0000000000000) /* abs(x) < 1.0 */ ++ { ++ if (ax == 0x0000000000000000) ++ /* x is +zero or -zero; return the same zero */ ++ return x; ++ else if (xneg) /* x < 0.0 */ ++ { ++ /* Return zero with the sign of x */ ++ PUT_BITS_DP64(SIGNBIT_DP64, x); ++ return x; ++ } ++ else ++ return 1.0; ++ } ++ else ++ { ++ rexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ /* Mask out the bits of r that we don't want */ ++ mask = (1L << (EXPSHIFTBITS_DP64 - rexp)) - 1; ++ ur = (ux & ~mask); ++ PUT_BITS_DP64(ur, r); ++ if (xneg || (ur == ux)) ++ return r; ++ else ++ /* We threw some bits away and x was positive */ ++ return r + 1.0; ++ } ++ ++} ++ ++weak_alias (__ceil, ceil) +diff -urpN libc/sysdeps/x86_64/fpu/s_ceilf.c libc-amd/sysdeps/x86_64/fpu/s_ceilf.c +--- libc/sysdeps/x86_64/fpu/s_ceilf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_ceilf.c 2006-03-22 03:41:02.000000000 +0100 +@@ -0,0 +1,60 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++float __ceilf(float x) ++{ ++ float r; ++ int rexp, xneg; ++ unsigned int ux, ax, ur, mask; ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ xneg = (ux != ax); ++ ++ if (ax >= 0x4b800000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^24 */ ++ if (ax > 0x7f800000) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ return x; ++ } ++ else if (ax < 0x3f800000) /* abs(x) < 1.0 */ ++ { ++ if (ax == 0x00000000) ++ /* x is +zero or -zero; return the same zero */ ++ return x; ++ else if (xneg) /* x < 0.0 */ ++ { ++ /* Return zero with the sign of x */ ++ PUT_BITS_SP32(SIGNBIT_SP32, x); ++ return x; ++ } ++ else ++ return 1.0F; ++ } ++ else ++ { ++ rexp = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ /* Mask out the bits of r that we don't want */ ++ mask = (1 << (EXPSHIFTBITS_SP32 - rexp)) - 1; ++ ur = (ux & ~mask); ++ PUT_BITS_SP32(ur, r); ++ ++ if (xneg || (ux == ur)) return r; ++ else ++ /* We threw some bits away and x was positive */ ++ return r + 1.0F; ++ } ++} ++ ++weak_alias (__ceilf, ceilf) +diff -urpN libc/sysdeps/x86_64/fpu/s_copysign.c libc-amd/sysdeps/x86_64/fpu/s_copysign.c +--- libc/sysdeps/x86_64/fpu/s_copysign.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_copysign.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,29 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++/* Returns the absolute value of x with the sign of y. ++ NaNs are not considered special; their sign bits are handled ++ the same as for any other number. */ ++ ++double __copysign(double x, double y) ++{ ++ /* This works on Hammer */ ++ double temp = -0.0; /* 0x8000000000000000 */ ++ /* AND the bit pattern with y, result in y */ ++ asm volatile ("andpd %0, %1" : : "x" (temp), "x" (y)); ++ /* AND the ones-complement of the bit pattern with x, result in temp */ ++ asm volatile ("andnpd %0, %1" : : "x" (x), "x" (temp)); ++ asm volatile ("orpd %0, %1" : : "x" (temp), "x" (y)); ++ return y; ++} ++ ++ ++weak_alias (__copysign, copysign) +diff -urpN libc/sysdeps/x86_64/fpu/s_copysignf.c libc-amd/sysdeps/x86_64/fpu/s_copysignf.c +--- libc/sysdeps/x86_64/fpu/s_copysignf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_copysignf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,29 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++ /* Returns the absolute value of x with the sign of y. ++ NaNs are not considered special; their sign bits are handled ++ the same as for any other number. */ ++ ++float __copysignf(float x, float y) ++{ ++ /* This works on Hammer */ ++ float temp = -0.0; /* 0x80000000 */ ++ /* AND the bit pattern with y, result in y */ ++ asm volatile ("andps %0, %1" : : "x" (temp), "x" (y)); ++ /* AND the ones-complement of the bit pattern with x, result in temp */ ++ asm volatile ("andnps %0, %1" : : "x" (x), "x" (temp)); ++ asm volatile ("orps %0, %1" : : "x" (temp), "x" (y)); ++ return y; ++} ++ ++ ++weak_alias (__copysignf, copysignf) +diff -urpN libc/sysdeps/x86_64/fpu/s_copysignf.S libc-amd/sysdeps/x86_64/fpu/s_copysignf.S +--- libc/sysdeps/x86_64/fpu/s_copysignf.S 2004-02-10 09:03:09.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_copysignf.S 1970-01-01 01:00:00.000000000 +0100 +@@ -1,49 +0,0 @@ +-/* copy sign, double version. +- Copyright (C) 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Andreas Jaeger <aj@suse.de>, 2002. +- +- 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 <machine/asm.h> +- +-#ifdef __ELF__ +- .section .rodata +-#else +- .text +-#endif +- +- .align ALIGNARG(4) +- ASM_TYPE_DIRECTIVE(mask,@object) +-mask: +- .byte 0xff, 0xff, 0xff, 0x7f +- ASM_SIZE_DIRECTIVE(mask) +- +-#ifdef PIC +-#define MO(op) op##(%rip) +-#else +-#define MO(op) op +-#endif +- +-ENTRY(__copysignf) +- movss MO(mask),%xmm3 +- andps %xmm3,%xmm0 +- andnps %xmm1,%xmm3 +- orps %xmm3,%xmm0 +- retq +-END (__copysignf) +- +-weak_alias (__copysignf, copysignf) +diff -urpN libc/sysdeps/x86_64/fpu/s_copysign.S libc-amd/sysdeps/x86_64/fpu/s_copysign.S +--- libc/sysdeps/x86_64/fpu/s_copysign.S 2002-08-31 12:33:06.000000000 +0200 ++++ libc-amd/sysdeps/x86_64/fpu/s_copysign.S 1970-01-01 01:00:00.000000000 +0100 +@@ -1,52 +0,0 @@ +-/* copy sign, double version. +- Copyright (C) 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Andreas Jaeger <aj@suse.de>, 2002. +- +- 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 <machine/asm.h> +- +-#ifdef __ELF__ +- .section .rodata +-#else +- .text +-#endif +- +- .align ALIGNARG(4) +- ASM_TYPE_DIRECTIVE(signmask,@object) +-signmask: +- .byte 0, 0, 0, 0, 0, 0, 0, 0x80 +- .byte 0, 0, 0, 0, 0, 0, 0, 0 +-othermask: +- .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +- .byte 0, 0, 0, 0, 0, 0, 0, 0 +- ASM_SIZE_DIRECTIVE(othermask) +- +-#ifdef PIC +-#define MO(op) op##(%rip) +-#else +-#define MO(op) op +-#endif +- +-ENTRY(__copysign) +- andpd MO(othermask),%xmm0 +- andpd MO(signmask),%xmm1 +- orpd %xmm1,%xmm0 +- ret +-END (__copysign) +- +-weak_alias (__copysign, copysign) +diff -urpN libc/sysdeps/x86_64/fpu/s_cos.c libc-amd/sysdeps/x86_64/fpu/s_cos.c +--- libc/sysdeps/x86_64/fpu/s_cos.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_cos.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/s_cosf.c libc-amd/sysdeps/x86_64/fpu/s_cosf.c +--- libc/sysdeps/x86_64/fpu/s_cosf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_cosf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/s_finite.c libc-amd/sysdeps/x86_64/fpu/s_finite.c +--- libc/sysdeps/x86_64/fpu/s_finite.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_finite.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,28 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++/* Returns 0 if x is infinite or NaN, otherwise returns 1 */ ++ ++int __finite(double x) ++{ ++ /* This works on Hammer */ ++ double temp = 1.0e444; /* = infinity = 0x7ff0000000000000 */ ++ volatile int retval; ++ retval = 0; ++ asm volatile ("andpd %0, %1;" : : "x" (temp), "x" (x)); ++ asm volatile ("comisd %0, %1" : : "x" (temp), "x" (x)); ++ asm volatile ("setnz %0" : "=g" (retval)); ++ return retval; ++} ++ ++hidden_def (__finite) ++weak_alias (__finite, finite) ++ +diff -urpN libc/sysdeps/x86_64/fpu/s_finitef.c libc-amd/sysdeps/x86_64/fpu/s_finitef.c +--- libc/sysdeps/x86_64/fpu/s_finitef.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_finitef.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,27 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++/* Returns 0 if x is infinite or NaN, otherwise returns 1 */ ++ ++int __finitef(float x) ++{ ++ /* This works on Hammer */ ++ float temp = 1.0e444; /* = infinity = 0x7f800000 */ ++ volatile int retval; ++ retval = 0; ++ asm volatile ("andps %0, %1;" : : "x" (temp), "x" (x)); ++ asm volatile ("comiss %0, %1" : : "x" (temp), "x" (x)); ++ asm volatile ("setnz %0" : "=g" (retval)); ++ return retval; ++} ++ ++hidden_def (__finitef) ++weak_alias (__finitef, finitef) +diff -urpN libc/sysdeps/x86_64/fpu/s_floor.c libc-amd/sysdeps/x86_64/fpu/s_floor.c +--- libc/sysdeps/x86_64/fpu/s_floor.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_floor.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,60 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++double __floor(double x) ++{ ++ double r; ++ long rexp, xneg; ++ ++ ++ unsigned long ux, ax, ur, mask; ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ xneg = (ux != ax); ++ ++ if (ax >= 0x4340000000000000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^53 */ ++ if (ax > 0x7ff0000000000000) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ return x; ++ } ++ else if (ax < 0x3ff0000000000000) /* abs(x) < 1.0 */ ++ { ++ if (ax == 0x0000000000000000) ++ /* x is +zero or -zero; return the same zero */ ++ return x; ++ else if (xneg) /* x < 0.0 */ ++ return -1.0; ++ else ++ return 0.0; ++ } ++ else ++ { ++ r = x; ++ rexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ /* Mask out the bits of r that we don't want */ ++ mask = (1L << (EXPSHIFTBITS_DP64 - rexp)) - 1; ++ ur = (ux & ~mask); ++ PUT_BITS_DP64(ur, r); ++ if (xneg && (ur != ux)) ++ /* We threw some bits away and x was negative */ ++ return r - 1.0; ++ else ++ return r; ++ } ++ ++} ++ ++weak_alias (__floor, floor) +diff -urpN libc/sysdeps/x86_64/fpu/s_floorf.c libc-amd/sysdeps/x86_64/fpu/s_floorf.c +--- libc/sysdeps/x86_64/fpu/s_floorf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_floorf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,56 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++float __floorf(float x) ++{ ++ float r; ++ int rexp, xneg; ++ unsigned int ux, ax, ur, mask; ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ xneg = (ux != ax); ++ ++ if (ax >= 0x4b800000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^24 */ ++ if (ax > 0x7f800000) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ return x; ++ } ++ else if (ax < 0x3f800000) /* abs(x) < 1.0 */ ++ { ++ if (ax == 0x00000000) ++ /* x is +zero or -zero; return the same zero */ ++ return x; ++ else if (xneg) /* x < 0.0 */ ++ return -1.0F; ++ else ++ return 0.0F; ++ } ++ else ++ { ++ rexp = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ /* Mask out the bits of r that we don't want */ ++ mask = (1 << (EXPSHIFTBITS_SP32 - rexp)) - 1; ++ ur = (ux & ~mask); ++ PUT_BITS_SP32(ur, r); ++ if (xneg && (ux != ur)) ++ /* We threw some bits away and x was negative */ ++ return r - 1.0F; ++ else ++ return r; ++ } ++} ++ ++weak_alias (__floorf, floorf) +diff -urpN libc/sysdeps/x86_64/fpu/s_fma.c libc-amd/sysdeps/x86_64/fpu/s_fma.c +--- libc/sysdeps/x86_64/fpu/s_fma.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_fma.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,117 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#include "libm_inlines_amd.h" ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++ ++double __fma(double a, double b, double sum) ++{ ++ /* Returns a * b + sum with no intermediate loss of precision */ ++ ++ double ha, ta, hb, tb, z, zz, r, s, az, asum; ++ int ua, ub, usum; ++ int scaled, expover, expunder, scaleexp; ++ unsigned long u; ++ ++ GET_BITS_DP64(a, u); ++ ua = (int)((u & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ GET_BITS_DP64(b, u); ++ ub = (int)((u & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ GET_BITS_DP64(sum, u); ++ usum = (int)((u & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ ++ if (ua == EMAX_DP64 + 1 || ub == EMAX_DP64 + 1 || usum == EMAX_DP64 + 1) ++ { ++ /* One or more of the arguments is NaN or infinity. The ++ result will also be NaN or infinity. */ ++ return a * b + sum; ++ } ++ else if (ua + ub > usum + 2 * MANTLENGTH_DP64) ++ { ++ /* sum is negligible compared with the extra-length product a*b */ ++ return a*b; ++ } ++ else if (usum > ua + ub + MANTLENGTH_DP64) ++ { ++ /* The product a*b is negligible compared with sum */ ++ return sum; ++ } ++ ++ expover = EMAX_DP64 - 2; ++ expunder = EMIN_DP64 + MANTLENGTH_DP64; ++ scaleexp = 0; ++ ++ ++ if (ua + ub > expover || usum > expover) ++ { ++ /* The result is likely to overflow. Scale down in an attempt ++ to avoid unnecessary overflow. The true result may still overflow. */ ++ scaled = 1; ++ scaleexp = expover / 2; ++ a = scaleDouble_1(a, -scaleexp); ++ b = scaleDouble_1(b, -scaleexp); ++ sum = scaleDouble_2(sum, -2*scaleexp); ++ } ++ else if (ua + ub < expunder) ++ { ++ /* The product a*b is near underflow; scale up */ ++ scaled = 1; ++ scaleexp = expunder / 2; ++ a = scaleDouble_1(a, -scaleexp); ++ b = scaleDouble_1(b, -scaleexp); ++ sum = scaleDouble_2(sum, -2*scaleexp); ++ } ++ else ++ scaled = 0; ++ ++ /* Split a into ha (head) and ta (tail). Do the same for b. */ ++ ha = a; ++ GET_BITS_DP64(ha, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, ha); ++ ta = a - ha; ++ hb = b; ++ GET_BITS_DP64(hb, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hb); ++ tb = b - hb; ++ ++ /* Carefully multiply the parts together. z is the most significant ++ part of the result, and zz the least significant part */ ++ z = a * b; ++ zz = (((ha * hb - z) + ha * tb) + ta * hb) + ta * tb; ++ ++ /* Set az = abs(z), asum = abs(sum) */ ++ GET_BITS_DP64(z, u); ++ u &= ~SIGNBIT_DP64; ++ PUT_BITS_DP64(u, az); ++ GET_BITS_DP64(sum, u); ++ u &= ~SIGNBIT_DP64; ++ PUT_BITS_DP64(u, asum); ++ ++ /* Carefully add (z,zz) to sum */ ++ r = z + sum; ++ ++ if (az > asum) ++ s = ((z - r) + sum) + zz; ++ else ++ s = ((sum - r) + z) + zz; ++ ++ if (scaled) ++ return scaleDouble_1(r + s, 2*scaleexp); ++ else ++ return r + s; ++} ++ ++weak_alias (__fma, fma) +diff -urpN libc/sysdeps/x86_64/fpu/s_fmaf.c libc-amd/sysdeps/x86_64/fpu/s_fmaf.c +--- libc/sysdeps/x86_64/fpu/s_fmaf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_fmaf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,116 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SCALEFLOAT_1 ++#define USE_SCALEFLOAT_2 ++#include "libm_inlines_amd.h" ++#undef USE_SCALEFLOAT_1 ++#undef USE_SCALEFLOAT_2 ++ ++float __fmaf(float a, float b, float sum) ++{ ++ /* Returns a * b + sum with no intermediate loss of precision */ ++ ++ float ha, ta, hb, tb, z, zz, r, s, az, asum; ++ int ua, ub, usum; ++ int scaled, expover, expunder, scaleexp; ++ unsigned int u; ++ ++ GET_BITS_SP32(a, u); ++ ua = (int)((u & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ GET_BITS_SP32(b, u); ++ ub = (int)((u & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ GET_BITS_SP32(sum, u); ++ usum = (int)((u & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ ++ if (ua == EMAX_SP32 + 1 || ub == EMAX_SP32 + 1 || usum == EMAX_SP32 + 1) ++ { ++ /* One or more of the arguments is NaN or infinity. The ++ result will also be NaN or infinity. */ ++ return a * b + sum; ++ } ++ else if (ua + ub > usum + 2 * MANTLENGTH_SP32) ++ { ++ /* sum is negligible compared with the extra-length product a*b */ ++ return a*b; ++ } ++ else if (usum > ua + ub + MANTLENGTH_SP32) ++ { ++ /* The product a*b is negligible compared with sum */ ++ return sum; ++ } ++ ++ expover = EMAX_SP32 - 2; ++ expunder = EMIN_SP32 + MANTLENGTH_SP32; ++ scaleexp = 0; ++ ++ if (ua + ub > expover || usum > expover) ++ { ++ /* The result is likely to overflow. Scale down in an attempt ++ to avoid unnecessary overflow. The true result may still overflow. */ ++ scaled = 1; ++ scaleexp = expover / 2; ++ a = scaleFloat_1(a, -scaleexp); ++ b = scaleFloat_1(b, -scaleexp); ++ sum = scaleFloat_2(sum, -2*scaleexp); ++ } ++ else if (ua + ub < expunder) ++ { ++ /* The product a*b is near underflow; scale up */ ++ scaled = 1; ++ scaleexp = expunder / 2; ++ a = scaleFloat_1(a, -scaleexp); ++ b = scaleFloat_1(b, -scaleexp); ++ sum = scaleFloat_2(sum, -2*scaleexp); ++ } ++ else ++ scaled = 0; ++ ++ /* Split a into ha (head) and ta (tail). Do the same for b. */ ++ ha = a; ++ GET_BITS_SP32(ha, u); ++ u &= 0xfffff000; ++ PUT_BITS_SP32(u, ha); ++ ta = a - ha; ++ hb = b; ++ GET_BITS_SP32(hb, u); ++ u &= 0xfffff000; ++ PUT_BITS_SP32(u, hb); ++ tb = b - hb; ++ ++ /* Carefully multiply the parts together. z is the most significant ++ part of the result, and zz the least significant part */ ++ z = a * b; ++ zz = (((ha * hb - z) + ha * tb) + ta * hb) + ta * tb; ++ ++ /* Set az = abs(z), asum = abs(sum) */ ++ GET_BITS_SP32(z, u); ++ u &= ~SIGNBIT_SP32; ++ PUT_BITS_SP32(u, az); ++ GET_BITS_SP32(sum, u); ++ u &= ~SIGNBIT_SP32; ++ PUT_BITS_SP32(u, asum); ++ ++ /* Carefully add (z,zz) to sum */ ++ r = z + sum; ++ ++ if (az > asum) ++ s = ((z - r) + sum) + zz; ++ else ++ s = ((sum - r) + z) + zz; ++ ++ if (scaled) ++ return scaleFloat_1(r + s, 2*scaleexp); ++ else ++ return r + s; ++} ++ ++weak_alias (__fmaf, fmaf) +diff -urpN libc/sysdeps/x86_64/fpu/s_logb.c libc-amd/sysdeps/x86_64/fpu/s_logb.c +--- libc/sysdeps/x86_64/fpu/s_logb.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_logb.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,62 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_INFINITY_WITH_FLAGS ++ ++double __logb(double x) ++{ ++ ++ unsigned long ux; ++ long u; ++ GET_BITS_DP64(x, ux); ++ u = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ if ((ux & ~SIGNBIT_DP64) == 0) ++ /* x is +/-zero. Return -infinity with div-by-zero flag. */ ++ return -infinity_with_flags(AMD_F_DIVBYZERO); ++ else if (EMIN_DP64 <= u && u <= EMAX_DP64) ++ /* x is a normal number */ ++ return u; ++ else if (u > EMAX_DP64) ++ { ++ /* x is infinity or NaN */ ++ if ((ux & MANTBITS_DP64) == 0) ++ /* x is +/-infinity. Return +infinity with no flags. */ ++ return infinity_with_flags(0); ++ else ++ /* x is NaN, result is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ } ++ else ++ { ++ /* x is denormalized. */ ++#ifdef FOLLOW_IEEE754_LOGB ++ /* Return the value of the minimum exponent to ensure that ++ the relationship between logb and scalb, defined in ++ IEEE 754, holds. */ ++ return EMIN_DP64; ++#else ++ /* Follow the rule set by IEEE 854 for logb */ ++ ux &= MANTBITS_DP64; ++ u = EMIN_DP64; ++ while (ux < IMPBIT_DP64) ++ { ++ ux <<= 1; ++ u--; ++ } ++ return u; ++#endif ++ } ++ ++} ++ ++weak_alias (__logb, logb) +diff -urpN libc/sysdeps/x86_64/fpu/s_logbf.c libc-amd/sysdeps/x86_64/fpu/s_logbf.c +--- libc/sysdeps/x86_64/fpu/s_logbf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_logbf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,60 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_INFINITYF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_INFINITYF_WITH_FLAGS ++ ++float __logbf(float x) ++{ ++ unsigned int ux; ++ int u; ++ GET_BITS_SP32(x, ux); ++ u = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ if ((ux & ~SIGNBIT_SP32) == 0) ++ /* x is +/-zero. Return -infinity with div-by-zero flag. */ ++ return -infinityf_with_flags(AMD_F_DIVBYZERO); ++ else if (EMIN_SP32 <= u && u <= EMAX_SP32) ++ /* x is a normal number */ ++ return u; ++ else if (u > EMAX_SP32) ++ { ++ /* x is infinity or NaN */ ++ if ((ux & MANTBITS_SP32) == 0) ++ /* x is +/-infinity. Return +infinity with no flags. */ ++ return infinityf_with_flags(0); ++ else ++ /* x is NaN, result is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ } ++ else ++ { ++ /* x is denormalized. */ ++#ifdef FOLLOW_IEEE754_LOGB ++ /* Return the value of the minimum exponent to ensure that ++ the relationship between logb and scalb, defined in ++ IEEE 754, holds. */ ++ return EMIN_SP32; ++#else ++ /* Follow the rule set by IEEE 854 for logb */ ++ ux &= MANTBITS_SP32; ++ u = EMIN_SP32; ++ while (ux < IMPBIT_SP32) ++ { ++ ux <<= 1; ++ u--; ++ } ++ return u; ++#endif ++ } ++} ++ ++weak_alias (__logbf, logbf) +diff -urpN libc/sysdeps/x86_64/fpu/s_modf.c libc-amd/sysdeps/x86_64/fpu/s_modf.c +--- libc/sysdeps/x86_64/fpu/s_modf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_modf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,59 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++double __modf(double x, double *iptr) ++{ ++ /* modf splits the argument x into integer and fraction parts, ++ each with the same sign as x. */ ++ ++ ++ long xexp; ++ unsigned long ux, ax, mask; ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ if (ax >= 0x4340000000000000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^53 */ ++ if (ax > 0x7ff0000000000000) ++ { ++ /* x is NaN */ ++ *iptr = x; ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ } ++ else ++ { ++ /* x is infinity or large. Return zero with the sign of x */ ++ *iptr = x; ++ PUT_BITS_DP64(ux & SIGNBIT_DP64, x); ++ return x; ++ } ++ } ++ else if (ax < 0x3ff0000000000000) ++ { ++ /* abs(x) < 1.0. Set iptr to zero with the sign of x ++ and return x. */ ++ PUT_BITS_DP64(ux & SIGNBIT_DP64, *iptr); ++ return x; ++ } ++ else ++ { ++ xexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ /* Mask out the bits of x that we don't want */ ++ mask = (1L << (EXPSHIFTBITS_DP64 - xexp)) - 1; ++ PUT_BITS_DP64(ux & ~mask, *iptr); ++ return x - *iptr; ++ } ++ ++} ++ ++weak_alias (__modf, modf) +diff -urpN libc/sysdeps/x86_64/fpu/s_modff.c libc-amd/sysdeps/x86_64/fpu/s_modff.c +--- libc/sysdeps/x86_64/fpu/s_modff.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_modff.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,54 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++float __modff(float x, float *iptr) ++{ ++ /* modff splits the argument x into integer and fraction parts, ++ each with the same sign as x. */ ++ ++ unsigned int ux, mask; ++ int xexp; ++ ++ GET_BITS_SP32(x, ux); ++ xexp = ((ux & (~SIGNBIT_SP32)) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ ++ if (xexp < 0) ++ { ++ /* abs(x) < 1.0. Set iptr to zero with the sign of x ++ and return x. */ ++ PUT_BITS_SP32(ux & SIGNBIT_SP32, *iptr); ++ return x; ++ } ++ else if (xexp < EXPSHIFTBITS_SP32) ++ { ++ /* x lies between 1.0 and 2**(24) */ ++ /* Mask out the bits of x that we don't want */ ++ mask = (1 << (EXPSHIFTBITS_SP32 - xexp)) - 1; ++ PUT_BITS_SP32(ux & ~mask, *iptr); ++ return x - *iptr; ++ } ++ else if ((ux & (~SIGNBIT_SP32)) > 0x7f800000) ++ { ++ /* x is NaN */ ++ *iptr = x; ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ } ++ else ++ { ++ /* x is infinity or large. Set iptr to x and return zero ++ with the sign of x. */ ++ *iptr = x; ++ PUT_BITS_SP32(ux & SIGNBIT_SP32, x); ++ return x; ++ } ++} ++ ++weak_alias (__modff, modff) +diff -urpN libc/sysdeps/x86_64/fpu/s_sin.c libc-amd/sysdeps/x86_64/fpu/s_sin.c +--- libc/sysdeps/x86_64/fpu/s_sin.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_sin.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/s_sincos.c libc-amd/sysdeps/x86_64/fpu/s_sincos.c +--- libc/sysdeps/x86_64/fpu/s_sincos.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_sincos.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,311 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_NAN_WITH_FLAGS ++#define USE_VAL_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++/* sin(x) approximation valid on the interval [-pi/4,pi/4]. */ ++static inline double sin_piby4(double x, double xx) ++{ ++ /* Taylor series for sin(x) is x - x^3/3! + x^5/5! - x^7/7! ... ++ = x * (1 - x^2/3! + x^4/5! - x^6/7! ... ++ = x * f(w) ++ where w = x*x and f(w) = (1 - w/3! + w^2/5! - w^3/7! ... ++ We use a minimax approximation of (f(w) - 1) / w ++ because this produces an expansion in even powers of x. ++ If xx (the tail of x) is non-zero, we add a correction ++ term g(x,xx) = (1-x*x/2)*xx to the result, where g(x,xx) ++ is an approximation to cos(x)*sin(xx) valid because ++ xx is tiny relative to x. ++ */ ++ static const double ++ c1 = -0.166666666666666646259241729, ++ c2 = 0.833333333333095043065222816e-2, ++ c3 = -0.19841269836761125688538679e-3, ++ c4 = 0.275573161037288022676895908448e-5, ++ c5 = -0.25051132068021699772257377197e-7, ++ c6 = 0.159181443044859136852668200e-9; ++ double x2, x3, r; ++ x2 = x * x; ++ x3 = x2 * x; ++ r = (c2 + x2 * (c3 + x2 * (c4 + x2 * (c5 + x2 * c6)))); ++ if (xx == 0.0) ++ return x + x3 * (c1 + x2 * r); ++ else ++ return x - ((x2 * (0.5 * xx - x3 * r) - xx) - x3 * c1); ++} ++ ++/* cos(x) approximation valid on the interval [-pi/4,pi/4]. */ ++static inline double cos_piby4(double x, double xx) ++{ ++ /* Taylor series for cos(x) is 1 - x^2/2! + x^4/4! - x^6/6! ... ++ = f(w) ++ where w = x*x and f(w) = (1 - w/2! + w^2/4! - w^3/6! ... ++ We use a minimax approximation of (f(w) - 1 + w/2) / (w*w) ++ because this produces an expansion in even powers of x. ++ If xx (the tail of x) is non-zero, we subtract a correction ++ term g(x,xx) = x*xx to the result, where g(x,xx) ++ is an approximation to sin(x)*sin(xx) valid because ++ xx is tiny relative to x. ++ */ ++ double r, x2, t; ++ static const double ++ c1 = 0.41666666666666665390037e-1, ++ c2 = -0.13888888888887398280412e-2, ++ c3 = 0.248015872987670414957399e-4, ++ c4 = -0.275573172723441909470836e-6, ++ c5 = 0.208761463822329611076335e-8, ++ c6 = -0.113826398067944859590880e-10; ++ ++ x2 = x * x; ++ r = 0.5 * x2; ++ t = 1.0 - r; ++ return t + ((((1.0 - t) - r) - x * xx) + x2 * x2 * ++ (c1 + x2 * (c2 + x2 * (c3 + x2 * (c4 + x2 * (c5 + x2 * c6)))))); ++} ++ ++void __sincos(double x, double *s, double *c) ++{ ++ double r, rr; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ GET_BITS_DP64(x, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax < 0x3e40000000000000) /* abs(x) < 2.0^(-27) */ ++ { ++ if (ax == 0x0000000000000000) ++ { ++ *s = x; ++ *c = 1.0; ++ } ++ else ++ { ++ *s = x; ++ *c = val_with_flags(1.0, AMD_F_INEXACT); ++ } ++ } ++ else ++ { ++ *s = x - x*x*x*0.166666666666666666; ++ *c = 1.0 - x*x*0.5; ++ } ++ } ++ else ++ { ++ *s = sin_piby4(x, 0.0); ++ *c = cos_piby4(x, 0.0); ++ } ++ return; ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ *s = *c = x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ *s = *c = nan_with_flags(AMD_F_INVALID); ++ return; ++ } ++ ++ xneg = (ax != ux); ++ ++ ++ if (xneg) ++ x = -x; ++ ++ /* Reduce x into range [-pi/4,pi/4] */ ++ __remainder_piby2(x, &r, &rr, ®ion); ++ ++ if (xneg) ++ { ++ switch (region) ++ { ++ default: ++ case 0: ++ *s = -sin_piby4(r, rr); ++ *c = cos_piby4(r, rr); ++ break; ++ case 1: ++ *s = -cos_piby4(r, rr); ++ *c = -sin_piby4(r, rr); ++ break; ++ case 2: ++ *s = sin_piby4(r, rr); ++ *c = -cos_piby4(r, rr); ++ break; ++ case 3: ++ *s = cos_piby4(r, rr); ++ *c = sin_piby4(r, rr); ++ break; ++ } ++ } ++ else ++ { ++ switch (region) ++ { ++ default: ++ case 0: ++ *s = sin_piby4(r, rr); ++ *c = cos_piby4(r, rr); ++ break; ++ case 1: ++ *s = cos_piby4(r, rr); ++ *c = -sin_piby4(r, rr); ++ break; ++ case 2: ++ *s = -sin_piby4(r, rr); ++ *c = -cos_piby4(r, rr); ++ break; ++ case 3: ++ *s = -cos_piby4(r, rr); ++ *c = sin_piby4(r, rr); ++ break; ++ } ++ } ++ return; ++} ++ ++double __sin(double x) ++{ ++ double r, rr; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ GET_BITS_DP64(x, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax < 0x3e40000000000000) /* abs(x) < 2.0^(-27) */ ++ { ++ if (ax == 0x0000000000000000) ++ return x; ++ else ++ return val_with_flags(x, AMD_F_INEXACT); ++ } ++ else ++ return x - x*x*x*0.166666666666666666; ++ } ++ else ++ return sin_piby4(x, 0.0); ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ xneg = (ax != ux); ++ ++ ++ if (xneg) ++ x = -x; ++ ++ /* Reduce x into range [-pi/4,pi/4] */ ++ __remainder_piby2(x, &r, &rr, ®ion); ++ ++ if (xneg) ++ { ++ switch (region) ++ { ++ default: ++ case 0: return -sin_piby4(r, rr); ++ case 1: return -cos_piby4(r, rr); ++ case 2: return sin_piby4(r, rr); ++ case 3: return cos_piby4(r, rr); ++ } ++ } ++ else ++ { ++ switch (region) ++ { ++ default: ++ case 0: return sin_piby4(r, rr); ++ case 1: return cos_piby4(r, rr); ++ case 2: return -sin_piby4(r, rr); ++ case 3: return -cos_piby4(r, rr); ++ } ++ } ++} ++ ++double __cos(double x) ++{ ++ double r, rr; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ GET_BITS_DP64(x, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax < 0x3e40000000000000) /* abs(x) < 2.0^(-27) */ ++ { ++ if (ax == 0x0000000000000000) /* abs(x) = 0.0 */ ++ return 1.0; ++ else ++ return val_with_flags(1.0, AMD_F_INEXACT); ++ } ++ else ++ return 1.0 - x*x*0.5; ++ } ++ else ++ return cos_piby4(x, 0.0); ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ xneg = (ax != ux); ++ ++ ++ if (xneg) ++ x = -x; ++ ++ /* Reduce x into range [-pi/4,pi/4] */ ++ __remainder_piby2(x, &r, &rr, ®ion); ++ ++ switch (region) ++ { ++ default: ++ case 0: return cos_piby4(r, rr); ++ case 1: return -sin_piby4(r, rr); ++ case 2: return -cos_piby4(r, rr); ++ case 3: return sin_piby4(r, rr); ++ } ++} ++ ++weak_alias (__sin, sin) ++weak_alias (__cos, cos) ++weak_alias (__sincos, sincos) +diff -urpN libc/sysdeps/x86_64/fpu/s_sincosf.c libc-amd/sysdeps/x86_64/fpu/s_sincosf.c +--- libc/sysdeps/x86_64/fpu/s_sincosf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_sincosf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,321 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_REMAINDER_PIBY2F_INLINE ++#define USE_VAL_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_VAL_WITH_FLAGS ++#undef USE_NAN_WITH_FLAGS ++#undef USE_REMAINDER_PIBY2F_INLINE ++ ++/* sin(x) approximation valid on the interval [-pi/4,pi/4]. */ ++static inline double sinf_piby4(double x) ++{ ++ /* Taylor series for sin(x) is x - x^3/3! + x^5/5! - x^7/7! ... ++ = x * (1 - x^2/3! + x^4/5! - x^6/7! ... ++ = x * f(w) ++ where w = x*x and f(w) = (1 - w/3! + w^2/5! - w^3/7! ... ++ We use a minimax approximation of (f(w) - 1) / w ++ because this produces an expansion in even powers of x. ++ */ ++ double x2; ++ static const double ++ c1 = -0.166666666638608441788607926e0, ++ c2 = 0.833333187633086262120839299e-2, ++ c3 = -0.198400874359527693921333720e-3, ++ c4 = 0.272500015145584081596826911e-5; ++ ++ x2 = x * x; ++ return (x + x * x2 * (c1 + x2 * (c2 + x2 * (c3 + x2 * c4)))); ++} ++ ++/* cos(x) approximation valid on the interval [-pi/4,pi/4]. */ ++static inline double cosf_piby4(double x) ++{ ++ /* Taylor series for cos(x) is 1 - x^2/2! + x^4/4! - x^6/6! ... ++ = f(w) ++ where w = x*x and f(w) = (1 - w/2! + w^2/4! - w^3/6! ... ++ We use a minimax approximation of (f(w) - 1 + w/2) / (w*w) ++ because this produces an expansion in even powers of x. ++ */ ++ double x2; ++ static const double ++ c1 = 0.41666666664325175238031e-1, ++ c2 = -0.13888887673175665567647e-2, ++ c3 = 0.24800600878112441958053e-4, ++ c4 = -0.27301013343179832472841e-6; ++ ++ x2 = x * x; ++ return (1.0 - 0.5 * x2 + (x2 * x2 * ++ (c1 + x2 * (c2 + x2 * (c3 + x2 * c4))))); ++} ++ ++ ++void __sincosf(float x, float *s, float *c) ++{ ++ double r, dx; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ ++ dx = x; ++ ++ GET_BITS_DP64(dx, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f80000000000000) /* abs(x) < 2.0^(-7) */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax == 0x0000000000000000) ++ { ++ *s = dx; ++ *c = 1.0; ++ } ++ else ++ { ++ *s = val_with_flags(dx, AMD_F_INEXACT); ++ *c = val_with_flags(1.0, AMD_F_INEXACT); ++ } ++ } ++ else ++ { ++ *s = dx - dx*dx*dx*0.166666666666666666; ++ *c = 1.0 - dx*dx*0.5; ++ } ++ } ++ else ++ { ++ *s = sinf_piby4(x); ++ *c = cosf_piby4(x); ++ } ++ return; ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ *s = *c = dx + dx; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ *s = *c = nan_with_flags(AMD_F_INVALID); ++ return; ++ } ++ ++ xneg = (ux >> 63); ++ ++ if (xneg) ++ dx = -dx; ++ ++ /* Reduce abs(x) into range [-pi/4,pi/4] */ ++ __remainder_piby2f_inline(dx, ax, &r, ®ion); ++ ++ if (xneg) ++ { ++ switch (region) ++ { ++ default: ++ case 0: ++ *s = -sinf_piby4(r); ++ *c = cosf_piby4(r); ++ break; ++ case 1: ++ *s = -cosf_piby4(r); ++ *c = -sinf_piby4(r); ++ break; ++ case 2: ++ *s = sinf_piby4(r); ++ *c = -cosf_piby4(r); ++ break; ++ case 3: ++ *s = cosf_piby4(r); ++ *c = sinf_piby4(r); ++ break; ++ } ++ } ++ else ++ { ++ switch (region) ++ { ++ default: ++ case 0: ++ *s = sinf_piby4(r); ++ *c = cosf_piby4(r); ++ break; ++ case 1: ++ *s = cosf_piby4(r); ++ *c = -sinf_piby4(r); ++ break; ++ case 2: ++ *s = -sinf_piby4(r); ++ *c = -cosf_piby4(r); ++ break; ++ case 3: ++ *s = -cosf_piby4(r); ++ *c = sinf_piby4(r); ++ break; ++ } ++ } ++} ++ ++float __sinf(float x) ++{ ++ double r, dx; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ ++ dx = x; ++ ++ GET_BITS_DP64(dx, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f80000000000000) /* abs(x) < 2.0^(-7) */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax == 0x0000000000000000) ++ return x; ++ else ++ return val_with_flags(dx, AMD_F_INEXACT); ++ } ++ else ++ return x - x*x*x*0.166666666666666666; ++ } ++ else ++ return sinf_piby4(dx); ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ ++ xneg = (ux >> 63); ++ ++ if (xneg) ++ dx = -dx; ++ ++ /* Reduce abs(x) into range [-pi/4,pi/4] */ ++ __remainder_piby2f_inline(dx, ax, &r, ®ion); ++ ++ if (xneg) ++ { ++ switch (region) ++ { ++ default: ++ case 0: return -sinf_piby4(r); ++ case 1: return -cosf_piby4(r); ++ case 2: return sinf_piby4(r); ++ case 3: return cosf_piby4(r); ++ } ++ } ++ else ++ { ++ switch (region) ++ { ++ default: ++ case 0: return sinf_piby4(r); ++ case 1: return cosf_piby4(r); ++ case 2: return -sinf_piby4(r); ++ case 3: return -cosf_piby4(r); ++ } ++ } ++} ++ ++#if 1 ++/* Stupidly, computing cosf via sincosf is much faster, ++ even though sincosf does the same work and more. */ ++float __cosf(float x) ++{ ++ float s, c; ++ __sincosf(x, &s, &c); ++ return c; ++} ++ ++#else ++/* This is the way cosf should be done, but it runs half ++ as fast as it ought to */ ++ ++float __cosf(float x) ++{ ++ double r, dx; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ ++ dx = x; ++ ++ GET_BITS_DP64(dx, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f80000000000000) /* abs(x) < 2.0^(-7) */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax == 0x0000000000000000) ++ return 1.0F; ++ else ++ return val_with_flags(1.0, AMD_F_INEXACT); ++ } ++ else ++ return 1.0F - x*x*0.5F; ++ } ++ else ++ return cosf_piby4(dx); ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ ++ xneg = (ux >> 63); ++ ++ if (xneg) ++ dx = -dx; ++ ++ /* Reduce abs(x) into range [-pi/4,pi/4] */ ++ __remainder_piby2f_inline(dx, ax, &r, ®ion); ++ ++ switch (region) ++ { ++ default: ++ case 0: return cosf_piby4(r); ++ case 1: return -sinf_piby4(r); ++ case 2: return -cosf_piby4(r); ++ case 3: return sinf_piby4(r); ++ } ++} ++#endif ++ ++weak_alias (__sinf, sinf) ++weak_alias (__cosf, cosf) ++weak_alias (__sincosf, sincosf) +diff -urpN libc/sysdeps/x86_64/fpu/s_sincos.S libc-amd/sysdeps/x86_64/fpu/s_sincos.S +--- libc/sysdeps/x86_64/fpu/s_sincos.S 2005-07-09 00:25:41.000000000 +0200 ++++ libc-amd/sysdeps/x86_64/fpu/s_sincos.S 1970-01-01 01:00:00.000000000 +0100 +@@ -1,61 +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, write to the Free +- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +- 02111-1307 USA. */ +- +-#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)) +diff -urpN libc/sysdeps/x86_64/fpu/s_sinf.c libc-amd/sysdeps/x86_64/fpu/s_sinf.c +--- libc/sysdeps/x86_64/fpu/s_sinf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_sinf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1 @@ ++/* Not needed. */ +diff -urpN libc/sysdeps/x86_64/fpu/s_tan.c libc-amd/sysdeps/x86_64/fpu/s_tan.c +--- libc/sysdeps/x86_64/fpu/s_tan.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_tan.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,220 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_NAN_WITH_FLAGS ++#define USE_VAL_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++ ++/* tan(x + xx) approximation valid on the interval [-pi/4,pi/4]. ++ If recip is true return -1/tan(x + xx) instead. */ ++static inline double tan_piby4(double x, double xx, int recip, int extra) ++{ ++ double r, t1, t2, xl; ++ int transform = 0; ++ static const double ++ piby4_lead = 7.85398163397448278999e-01, /* 0x3fe921fb54442d18 */ ++ piby4_tail = 3.06161699786838240164e-17; /* 0x3c81a62633145c06 */ ++ ++ /* In order to maintain relative precision transform using the identity: ++ tan(pi/4-x) = (1-tan(x))/(1+tan(x)) for arguments close to pi/4. ++ Similarly use tan(x-pi/4) = (tan(x)-1)/(tan(x)+1) close to -pi/4. */ ++ ++ if (x > 0.68) ++ { ++ transform = 1; ++ x = piby4_lead - x; ++ xl = piby4_tail - xx; ++ x += xl; ++ xx = 0.0; ++ } ++ else if (x < -0.68) ++ { ++ transform = -1; ++ x = piby4_lead + x; ++ xl = piby4_tail + xx; ++ x += xl; ++ xx = 0.0; ++ } ++ ++ /* Core Remez [2,3] approximation to tan(x+xx) on the ++ interval [0,0.68]. */ ++ ++ r = x*x + 2.0 * x * xx; ++ t1 = x; ++ t2 = xx + x*r* ++ (0.372379159759792203640806338901e0 + ++ (-0.229345080057565662883358588111e-1 + ++ 0.224044448537022097264602535574e-3*r)*r)/ ++ (0.111713747927937668539901657944e1 + ++ (-0.515658515729031149329237816945e0 + ++ (0.260656620398645407524064091208e-1 - ++ 0.232371494088563558304549252913e-3*r)*r)*r); ++ ++ /* Reconstruct tan(x) in the transformed case. */ ++ ++ if (transform) ++ { ++ double t; ++ t = t1 + t2; ++ if (recip) ++ return transform*(2*t/(t-1) - 1.0); ++ else ++ return transform*(1.0 - 2*t/(1+t)); ++ } ++ ++ if (recip) ++ { ++ if (extra) ++ { ++ /* Compute -1.0/(t1 + t2) accurately */ ++ double trec, trec_top, z1, z2, t; ++ unsigned long u; ++ t = t1 + t2; ++ GET_BITS_DP64(t, u); ++ u &= 0xffffffff00000000; ++ PUT_BITS_DP64(u, z1); ++ z2 = t2 - (z1 - t1); ++ trec = -1.0 / t; ++ GET_BITS_DP64(trec, u); ++ u &= 0xffffffff00000000; ++ PUT_BITS_DP64(u, trec_top); ++ return trec_top + trec * ((1.0 + trec_top * z1) + trec_top * z2); ++ } ++ else ++ return -1.0/(t1 + t2); ++ ++ } ++ else ++ return t1 + t2; ++} ++ ++ ++double __tan(double x) ++{ ++ double r, rr; ++ int region, xneg; ++ int extra = 0 ; // does tan_piby4 need extra accuracy on reciprocal? ++ ++ unsigned long ux, ax; ++ GET_BITS_DP64(x, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax < 0x3e40000000000000) /* abs(x) < 2.0^(-27) */ ++ { ++ if (ax == 0x0000000000000000) return x; ++ else return val_with_flags(x, AMD_F_INEXACT); ++ } ++ else ++ { ++ return x + x*x*x*0.333333333333333333; ++ } ++ } ++ else ++ return tan_piby4(x, 0.0, 0, 0); ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ xneg = (ax != ux); ++ ++ ++ if (xneg) ++ x = -x; ++ ++ if (x < 5.0e5) ++ { ++ /* For these size arguments we can just carefully subtract the ++ appropriate multiple of pi/2, using extra precision where ++ x is close to an exact multiple of pi/2 */ ++ static const double ++ twobypi = 6.36619772367581382433e-01, /* 0x3fe45f306dc9c883 */ ++ piby2_1 = 1.57079632673412561417e+00, /* 0x3ff921fb54400000 */ ++ piby2_1tail = 6.07710050650619224932e-11, /* 0x3dd0b4611a626331 */ ++ piby2_2 = 6.07710050630396597660e-11, /* 0x3dd0b4611a600000 */ ++ piby2_2tail = 2.02226624879595063154e-21, /* 0x3ba3198a2e037073 */ ++ piby2_3 = 2.02226624871116645580e-21, /* 0x3ba3198a2e000000 */ ++ piby2_3tail = 8.47842766036889956997e-32; /* 0x397b839a252049c1 */ ++ double t, rhead, rtail; ++ int npi2; ++ unsigned long uy, xexp, expdiff; ++ xexp = ax >> EXPSHIFTBITS_DP64; ++ /* How many pi/2 is x a multiple of? */ ++ if (ax <= 0x400f6a7a2955385e) /* 5pi/4 */ ++ { ++ if (ax <= 0x4002d97c7f3321d2) /* 3pi/4 */ ++ npi2 = 1; ++ else ++ npi2 = 2; ++ } ++ else if (ax <= 0x401c463abeccb2bb) /* 9pi/4 */ ++ { ++ if (ax <= 0x4015fdbbe9bba775) /* 7pi/4 */ ++ npi2 = 3; ++ else ++ npi2 = 4; ++ } ++ else ++ npi2 = (int)(x * twobypi + 0.5); ++ /* Subtract the multiple from x to get an extra-precision remainder */ ++ rhead = x - npi2 * piby2_1; ++ rtail = npi2 * piby2_1tail; ++ GET_BITS_DP64(rhead, uy); ++ expdiff = xexp - ((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ if (expdiff > 15) ++ { ++ /* The remainder is pretty small compared with x, which ++ implies that x is a near multiple of pi/2 ++ (x matches the multiple to at least 15 bits) */ ++ t = rhead; ++ rtail = npi2 * piby2_2; ++ rhead = t - rtail; ++ rtail = npi2 * piby2_2tail - ((t - rhead) - rtail); ++ if (expdiff > 48) ++ { ++ /* x matches a pi/2 multiple to at least 48 bits */ ++ t = rhead; ++ rtail = npi2 * piby2_3; ++ rhead = t - rtail; ++ rtail = npi2 * piby2_3tail - ((t - rhead) - rtail); ++ } ++ } ++ r = rhead - rtail; ++ rr = (rhead - r) - rtail; ++ region = npi2 & 3; ++ } ++ else ++ { ++ /* Reduce x into range [-pi/4,pi/4] */ ++ __remainder_piby2(x, &r, &rr, ®ion); ++ extra = 1; ++ } ++ ++ if (xneg) ++ return -tan_piby4(r, rr, region & 1, extra); ++ else ++ return tan_piby4(r, rr, region & 1, extra); ++} ++ ++weak_alias (__tan, tan) +diff -urpN libc/sysdeps/x86_64/fpu/s_tanf.c libc-amd/sysdeps/x86_64/fpu/s_tanf.c +--- libc/sysdeps/x86_64/fpu/s_tanf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_tanf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,97 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_REMAINDER_PIBY2F_INLINE ++#define USE_VAL_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_VAL_WITH_FLAGS ++#undef USE_NAN_WITH_FLAGS ++#undef USE_REMAINDER_PIBY2F_INLINE ++ ++/* tan(x) approximation valid on the interval [-pi/4,pi/4]. ++ If recip is true return -1/tan(x) instead. */ ++static inline double tanf_piby4(double x, int recip) ++{ ++ double r, t; ++ ++ /* Core Remez [1,2] approximation to tan(x) on the ++ interval [0,pi/4]. */ ++ r = x*x; ++ t = x + x*r* ++ (0.385296071263995406715129e0 - ++ 0.172032480471481694693109e-1 * r) / ++ (0.115588821434688393452299e+1 + ++ (-0.51396505478854532132342e0 + ++ 0.1844239256901656082986661e-1 * r) * r); ++ ++ if (recip) ++ return -1.0 / t; ++ else ++ return t; ++} ++ ++float __tanf(float x) ++{ ++ double r, dx; ++ int region, xneg; ++ ++ unsigned long ux, ax; ++ ++ dx = x; ++ ++ GET_BITS_DP64(dx, ux); ++ ax = (ux & ~SIGNBIT_DP64); ++ ++ if (ax <= 0x3fe921fb54442d18) /* abs(x) <= pi/4 */ ++ { ++ if (ax < 0x3f80000000000000) /* abs(x) < 2.0^(-7) */ ++ { ++ if (ax < 0x3f20000000000000) /* abs(x) < 2.0^(-13) */ ++ { ++ if (ax == 0x0000000000000000) ++ return dx; ++ else ++ return val_with_flags(dx, AMD_F_INEXACT); ++ } ++ else ++ return dx + dx*dx*dx*0.333333333333333333; ++ } ++ else ++ return tanf_piby4(dx, 0); ++ } ++ else if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return dx + dx; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity. Return a NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ ++ xneg = (ux >> 63); ++ ++ if (xneg) ++ x = -x; ++ ++ /* Reduce x into range [-pi/4,pi/4] */ ++ __remainder_piby2f_inline(x, ax, &r, ®ion); ++ ++ if (xneg) ++ return -tanf_piby4(r, region & 1); ++ else ++ return tanf_piby4(r, region & 1); ++} ++ ++weak_alias (__tanf, tanf) +diff -urpN libc/sysdeps/x86_64/fpu/s_trunc.c libc-amd/sysdeps/x86_64/fpu/s_trunc.c +--- libc/sysdeps/x86_64/fpu/s_trunc.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_trunc.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,48 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++double __trunc(double x) ++{ ++ double r; ++ long rexp; ++ unsigned long ux, ax, mask; ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ if (ax >= 0x4340000000000000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^53 */ ++ if (ax > 0x7ff0000000000000) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ return x; ++ } ++ else if (ax < 0x3ff0000000000000) /* abs(x) < 1.0 */ ++ { ++ /* Return zero with the sign of x */ ++ PUT_BITS_DP64(ux & SIGNBIT_DP64, x); ++ return x; ++ } ++ else ++ { ++ r = x; ++ rexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ /* Mask out the bits of r that we don't want */ ++ mask = (1L << (EXPSHIFTBITS_DP64 - rexp)) - 1; ++ PUT_BITS_DP64(ux & ~mask, r); ++ return r; ++ } ++ ++} ++ ++weak_alias (__trunc, trunc) +diff -urpN libc/sysdeps/x86_64/fpu/s_truncf.c libc-amd/sysdeps/x86_64/fpu/s_truncf.c +--- libc/sysdeps/x86_64/fpu/s_truncf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/s_truncf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,47 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++float __truncf(float x) ++{ ++ float r; ++ int rexp; ++ unsigned int ux, ax, mask; ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ ++ if (ax >= 0x4b800000) ++ { ++ /* abs(x) is either NaN, infinity, or >= 2^24 */ ++ if (ax > 0x7f800000) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ return x; ++ } ++ else if (ax < 0x3f800000) /* abs(x) < 1.0 */ ++ { ++ /* Return zero with the sign of x */ ++ PUT_BITS_SP32(ux & SIGNBIT_SP32, x); ++ return x; ++ } ++ else ++ { ++ r = x; ++ rexp = ((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ /* Mask out the bits of r that we don't want */ ++ mask = (1 << (EXPSHIFTBITS_SP32 - rexp)) - 1; ++ PUT_BITS_SP32(ux & ~mask, r); ++ return r; ++ } ++} ++ ++weak_alias (__truncf, truncf) +diff -urpN libc/sysdeps/x86_64/fpu/w_acos.c libc-amd/sysdeps/x86_64/fpu/w_acos.c +--- libc/sysdeps/x86_64/fpu/w_acos.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_acos.c 2006-03-22 02:20:46.000000000 +0100 +@@ -0,0 +1,140 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VAL_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range argument */ ++static inline double retval_errno_edom(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = DOMAIN; ++ exc.name = (char *)"acos"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = nan_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++ (void)fputs("acos: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++double __acos(double x) ++{ ++ /* Computes arccos(x). ++ The argument is first reduced by noting that arccos(x) ++ is invalid for abs(x) > 1. For denormal and small ++ arguments arccos(x) = pi/2 to machine accuracy. ++ Remaining argument ranges are handled as follows. ++ For abs(x) <= 0.5 use ++ arccos(x) = pi/2 - arcsin(x) ++ = pi/2 - (x + x^3*R(x^2)) ++ where R(x^2) is a rational minimax approximation to ++ (arcsin(x) - x)/x^3. ++ For abs(x) > 0.5 exploit the identity: ++ arccos(x) = pi - 2*arcsin(sqrt(1-x)/2) ++ together with the above rational approximation, and ++ reconstruct the terms carefully. ++ */ ++ ++ /* Some constants and split constants. */ ++ ++ static const double ++ pi = 3.1415926535897933e+00, /* 0x400921fb54442d18 */ ++ piby2 = 1.5707963267948965580e+00, /* 0x3ff921fb54442d18 */ ++ piby2_head = 1.5707963267948965580e+00, /* 0x3ff921fb54442d18 */ ++ piby2_tail = 6.12323399573676603587e-17; /* 0x3c91a62633145c07 */ ++ ++ double u, y, s=0.0, r; ++ int xexp, xnan, transform=0; ++ ++ unsigned long ux, aux, xneg; ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ xneg = (ux & SIGNBIT_DP64); ++ xnan = (aux > PINFBITPATT_DP64); ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ ++ /* Special cases */ ++ ++ if (xexp < -56) ++ { /* y small enough that arccos(x) = pi/2 */ ++ return val_with_flags(piby2, AMD_F_INEXACT); ++ } ++ else if (xnan) return x + x; ++ else if (xexp >= 0) ++ { /* abs(x) >= 1.0 */ ++ if (x == 1.0) return 0.0; ++ else if (x == -1.0) return val_with_flags(pi, AMD_F_INEXACT); ++ else return retval_errno_edom(x); ++ } ++ ++ if (xneg) y = -x; ++ else y = x; ++ ++ transform = (xexp >= -1); /* abs(x) >= 0.5 */ ++ ++ if (transform) ++ { /* Transform y into the range [0,0.5) */ ++ transform = 1; ++ r = 0.5*(1-y); ++ /* Hammer sqrt instruction */ ++ asm volatile ("sqrtsd %1, %0" : "=x" (s) : "x" (r)); ++ y = s; ++ } ++ else ++ r = y*y; ++ ++ /* Use a rational approximation for [0.0, 0.5] */ ++ ++ u = r*(0.227485835556935010735943483075 + ++ (-0.445017216867635649900123110649 + ++ (0.275558175256937652532686256258 + ++ (-0.0549989809235685841612020091328 + ++ (0.00109242697235074662306043804220 + ++ 0.0000482901920344786991880522822991*r)*r)*r)*r)*r)/ ++ (1.36491501334161032038194214209 + ++ (-3.28431505720958658909889444194 + ++ (2.76568859157270989520376345954 + ++ (-0.943639137032492685763471240072 + ++ 0.105869422087204370341222318533*r)*r)*r)*r); ++ ++ if (transform) ++ { /* Reconstruct acos carefully in transformed region */ ++ if (xneg) return pi - 2*(s+(y*u - piby2_tail)); ++ else ++ { ++ double c, s1; ++ unsigned long us; ++ GET_BITS_DP64(s, us); ++ PUT_BITS_DP64(0xffffffff00000000 & us, s1); ++ c = (r-s1*s1)/(s+s1); ++ return 2*s1 + (2*c+2*y*u); ++ } ++ } ++ else ++ return piby2_head - (x - (piby2_tail - x*u)); ++} ++ ++weak_alias (__acos, acos) +diff -urpN libc/sysdeps/x86_64/fpu/w_acosf.c libc-amd/sysdeps/x86_64/fpu/w_acosf.c +--- libc/sysdeps/x86_64/fpu/w_acosf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_acosf.c 2006-03-22 02:21:25.000000000 +0100 +@@ -0,0 +1,142 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VALF_WITH_FLAGS ++#define USE_NANF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NANF_WITH_FLAGS ++#undef USE_VALF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range argument */ ++static inline float retval_errno_edom(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = DOMAIN; ++ exc.name = (char *)"acosf"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = nanf_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++ (void)fputs("acosf: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++float __acosf(float x) ++{ ++ /* Computes arccos(x). ++ The argument is first reduced by noting that arccos(x) ++ is invalid for abs(x) > 1. For denormal and small ++ arguments arccos(x) = pi/2 to machine accuracy. ++ Remaining argument ranges are handled as follows. ++ For abs(x) <= 0.5 use ++ arccos(x) = pi/2 - arcsin(x) ++ = pi/2 - (x + x^3*R(x^2)) ++ where R(x^2) is a rational minimax approximation to ++ (arcsin(x) - x)/x^3. ++ For abs(x) > 0.5 exploit the identity: ++ arccos(x) = pi - 2*arcsin(sqrt(1-x)/2) ++ together with the above rational approximation, and ++ reconstruct the terms carefully. ++ */ ++ ++ /* Some constants and split constants. */ ++ ++ static const float ++ piby2 = 1.5707963705e+00F; /* 0x3fc90fdb */ ++ static const double ++ pi = 3.1415926535897933e+00, /* 0x400921fb54442d18 */ ++ piby2_head = 1.5707963267948965580e+00, /* 0x3ff921fb54442d18 */ ++ piby2_tail = 6.12323399573676603587e-17; /* 0x3c91a62633145c07 */ ++ ++ float u, y, s = 0.0F, r; ++ int xexp, xnan, transform = 0; ++ ++ unsigned int ux, aux, xneg; ++ ++ ++ GET_BITS_SP32(x, ux); ++ /* ++ ux = (*((unsigned int *)&x)); ++ */ ++ aux = ux & ~SIGNBIT_SP32; ++ xneg = (ux & SIGNBIT_SP32); ++ xnan = (aux > PINFBITPATT_SP32); ++ xexp = (int)((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ ++ /* Special cases */ ++ ++ if (xexp < -26) ++ /* y small enough that arccos(x) = pi/2 */ ++ return valf_with_flags(piby2, AMD_F_INEXACT); ++ else if (xnan) return x + x; ++ else if (xexp >= 0) ++ { /* abs(x) >= 1.0 */ ++ if (x == 1.0F) return 0.0F; ++ else if (x == -1.0F) return valf_with_flags(pi, AMD_F_INEXACT); ++ else return retval_errno_edom(x); ++ } ++ ++ if (xneg) y = -x; ++ else y = x; ++ ++ transform = (xexp >= -1); /* abs(x) >= 0.5 */ ++ ++ if (transform) ++ { /* Transform y into the range [0,0.5) */ ++ transform = 1; ++ r = 0.5F*(1-y); ++ /* Hammer sqrt instruction */ ++ asm volatile ("sqrtss %1, %0" : "=x" (s) : "x" (r)); ++ y = s; ++ } ++ else ++ r = y*y; ++ ++ /* Use a rational approximation for [0.0, 0.5] */ ++ ++ u=r*(0.184161606965100694821398249421F + ++ (-0.0565298683201845211985026327361F + ++ (-0.0133819288943925804214011424456F - ++ 0.00396137437848476485201154797087F*r)*r)*r)/ ++ (1.10496961524520294485512696706F - ++ 0.836411276854206731913362287293F*r); ++ ++ if (transform) ++ { ++ /* Reconstruct acos carefully in transformed region */ ++ if (xneg) ++ return pi - 2.0F*(s+(y*u - piby2_tail)); ++ else ++ { ++ float c, s1; ++ unsigned int us; ++ GET_BITS_SP32(s, us); ++ PUT_BITS_SP32(0xffff0000 & us, s1); ++ c = (r-s1*s1)/(s+s1); ++ return 2.0F*s1 + (2.0F*c+2.0F*y*u); ++ } ++ } ++ else ++ return piby2_head - (x - (piby2_tail - x*u)); ++} ++ ++weak_alias (__acosf, acosf) +diff -urpN libc/sysdeps/x86_64/fpu/w_asin.c libc-amd/sysdeps/x86_64/fpu/w_asin.c +--- libc/sysdeps/x86_64/fpu/w_asin.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_asin.c 2006-03-22 02:21:50.000000000 +0100 +@@ -0,0 +1,145 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VAL_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range argument */ ++static inline double retval_errno_edom(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = DOMAIN; ++ exc.name = (char *)"asin"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = nan_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++ (void)fputs("asin: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++double __asin(double x) ++{ ++ /* Computes arcsin(x). ++ The argument is first reduced by noting that arcsin(x) ++ is invalid for abs(x) > 1 and arcsin(-x) = -arcsin(x). ++ For denormal and small arguments arcsin(x) = x to machine ++ accuracy. Remaining argument ranges are handled as follows. ++ For abs(x) <= 0.5 use ++ arcsin(x) = x + x^3*R(x^2) ++ where R(x^2) is a rational minimax approximation to ++ (arcsin(x) - x)/x^3. ++ For abs(x) > 0.5 exploit the identity: ++ arcsin(x) = pi/2 - 2*arcsin(sqrt(1-x)/2) ++ together with the above rational approximation, and ++ reconstruct the terms carefully. ++ */ ++ ++ /* Some constants and split constants. */ ++ ++ static const double ++ piby2_tail = 6.1232339957367660e-17, /* 0x3c91a62633145c07 */ ++ hpiby2_head = 7.8539816339744831e-01, /* 0x3fe921fb54442d18 */ ++ piby2 = 1.5707963267948965e+00; /* 0x3ff921fb54442d18 */ ++ double u, v, y, s=0.0, r; ++ int xexp, xnan, transform=0; ++ ++ unsigned long ux, aux, xneg; ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ xneg = (ux & SIGNBIT_DP64); ++ xnan = (aux > PINFBITPATT_DP64); ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ ++ /* Special cases */ ++ ++ if (xexp < -28) ++ { /* y small enough that arcsin(x) = x */ ++ return val_with_flags(x, AMD_F_INEXACT); ++ } ++ else if (xnan) return x + x; ++ else if (xexp >= 0) ++ { /* abs(x) >= 1.0 */ ++ if (x == 1.0) return val_with_flags(piby2, AMD_F_INEXACT); ++ else if (x == -1.0) return val_with_flags(-piby2, AMD_F_INEXACT); ++ else return retval_errno_edom(x); ++ ++ } ++ ++ if (xneg) y = -x; ++ else y = x; ++ ++ transform = (xexp >= -1); /* abs(x) >= 0.5 */ ++ ++ if (transform) ++ { /* Transform y into the range [0,0.5) */ ++ transform = 1; ++ r = 0.5*(1-y); ++ /* Hammer sqrt instruction */ ++ asm volatile ("sqrtsd %1, %0" : "=x" (s) : "x" (r)); ++ y = s; ++ } ++ else ++ { ++ r = y*y; ++ } ++ ++ /* Use a rational approximation for [0.0, 0.5] */ ++ ++ u = r*(0.227485835556935010735943483075 + ++ (-0.445017216867635649900123110649 + ++ (0.275558175256937652532686256258 + ++ (-0.0549989809235685841612020091328 + ++ (0.00109242697235074662306043804220 + ++ 0.0000482901920344786991880522822991*r)*r)*r)*r)*r)/ ++ (1.36491501334161032038194214209 + ++ (-3.28431505720958658909889444194 + ++ (2.76568859157270989520376345954 + ++ (-0.943639137032492685763471240072 + ++ 0.105869422087204370341222318533*r)*r)*r)*r); ++ ++ if (transform) ++ { /* Reconstruct asin carefully in transformed region */ ++ { ++ double c, s1, p, q; ++ unsigned long us; ++ GET_BITS_DP64(s, us); ++ PUT_BITS_DP64(0xffffffff00000000 & us, s1); ++ c = (r-s1*s1)/(s+s1); ++ p = 2*s*u-(piby2_tail-2*c); ++ q = hpiby2_head-2*s1; ++ v = hpiby2_head-(p-q); ++ } ++ } ++ else ++ { ++ v = y + y*u; ++ } ++ ++ if (xneg) return -v; ++ else return v; ++} ++ ++weak_alias (__asin, asin) +diff -urpN libc/sysdeps/x86_64/fpu/w_asinf.c libc-amd/sysdeps/x86_64/fpu/w_asinf.c +--- libc/sysdeps/x86_64/fpu/w_asinf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_asinf.c 2006-03-22 02:22:20.000000000 +0100 +@@ -0,0 +1,134 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_VALF_WITH_FLAGS ++#define USE_NANF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NANF_WITH_FLAGS ++#undef USE_VALF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range argument */ ++static inline float retval_errno_edom(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = DOMAIN; ++ exc.name = (char *)"asinf"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = nanf_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++ (void)fputs("asinf: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++float __asinf(float x) ++{ ++ /* Computes arcsin(x). ++ The argument is first reduced by noting that arcsin(x) ++ is invalid for abs(x) > 1 and arcsin(-x) = -arcsin(x). ++ For denormal and small arguments arcsin(x) = x to machine ++ accuracy. Remaining argument ranges are handled as follows. ++ For abs(x) <= 0.5 use ++ arcsin(x) = x + x^3*R(x^2) ++ where R(x^2) is a rational minimax approximation to ++ (arcsin(x) - x)/x^3. ++ For abs(x) > 0.5 exploit the identity: ++ arcsin(x) = pi/2 - 2*arcsin(sqrt(1-x)/2) ++ together with the above rational approximation, and ++ reconstruct the terms carefully. ++ */ ++ ++ /* Some constants and split constants. */ ++ ++ static const float ++ piby2_tail = 7.5497894159e-08F, /* 0x33a22168 */ ++ hpiby2_head = 7.8539812565e-01F, /* 0x3f490fda */ ++ piby2 = 1.5707963705e+00F; /* 0x3fc90fdb */ ++ float u, v, y, s = 0.0F, r; ++ int xexp, xnan, transform = 0; ++ ++ unsigned int ux, aux, xneg; ++ GET_BITS_SP32(x, ux); ++ aux = ux & ~SIGNBIT_SP32; ++ xneg = (ux & SIGNBIT_SP32); ++ xnan = (aux > PINFBITPATT_SP32); ++ xexp = (int)((ux & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32; ++ ++ /* Special cases */ ++ ++ if (xexp < -14) ++ /* y small enough that arcsin(x) = x */ ++ return valf_with_flags(x, AMD_F_INEXACT); ++ else if (xnan) return x + x; ++ else if (xexp >= 0) ++ { ++ /* abs(x) >= 1.0 */ ++ if (x == 1.0F) return valf_with_flags(piby2, AMD_F_INEXACT); ++ else if (x == -1.0F) return valf_with_flags(-piby2, AMD_F_INEXACT); ++ else return retval_errno_edom(x); ++ } ++ ++ if (xneg) y = -x; ++ else y = x; ++ ++ transform = (xexp >= -1); /* abs(x) >= 0.5 */ ++ ++ if (transform) ++ { /* Transform y into the range [0,0.5) */ ++ transform = 1; ++ r = 0.5F*(1-y); ++ /* Hammer sqrt instruction */ ++ asm volatile ("sqrtss %1, %0" : "=x" (s) : "x" (r)); ++ y = s; ++ } ++ else ++ r = y*y; ++ ++ /* Use a rational approximation for [0.0, 0.5] */ ++ ++ u=r*(0.184161606965100694821398249421F + ++ (-0.0565298683201845211985026327361F + ++ (-0.0133819288943925804214011424456F - ++ 0.00396137437848476485201154797087F*r)*r)*r)/ ++ (1.10496961524520294485512696706F - ++ 0.836411276854206731913362287293F*r); ++ ++ if (transform) ++ { ++ /* Reconstruct asin carefully in transformed region */ ++ float c, s1, p, q; ++ unsigned int us; ++ GET_BITS_SP32(s, us); ++ PUT_BITS_SP32(0xffff0000 & us, s1); ++ c = (r-s1*s1)/(s+s1); ++ p = 2.0F*s*u-(piby2_tail-2.0F*c); ++ q = hpiby2_head-2*s1; ++ v = hpiby2_head-(p-q); ++ } ++ else ++ v = y + y*u; ++ ++ if (xneg) return -v; ++ else return v; ++} ++ ++weak_alias (__asinf, asinf) +diff -urpN libc/sysdeps/x86_64/fpu/w_cosh.c libc-amd/sysdeps/x86_64/fpu/w_cosh.c +--- libc/sysdeps/x86_64/fpu/w_cosh.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_cosh.c 2006-03-22 02:23:24.000000000 +0100 +@@ -0,0 +1,347 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_INFINITY_WITH_FLAGS ++#define USE_VAL_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_INFINITY_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"cosh"; ++ if (_LIB_VERSION == _SVID_) ++ { ++ exc.retval = HUGE; ++ } ++ else ++ { ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW); ++ } ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++ ++double __cosh(double x) ++{ ++ /* ++ Derived from sinh subroutine ++ ++ After dealing with special cases the computation is split into ++ regions as follows: ++ ++ abs(x) >= max_cosh_arg: ++ cosh(x) = sign(x)*Inf ++ ++ abs(x) >= small_threshold: ++ cosh(x) = sign(x)*exp(abs(x))/2 computed using the ++ splitexp and scaleDouble functions as for exp_amd(). ++ ++ abs(x) < small_threshold: ++ compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) ++ cosh(x) is then sign(x)*z. */ ++ ++ static const double ++ max_cosh_arg = 7.10475860073943977113e+02, /* 0x408633ce8fb9f87e */ ++ thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ ++ log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ ++ log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ ++// small_threshold = 8*BASEDIGITS_DP64*0.30102999566398119521373889; ++ small_threshold = 20.0; ++ /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ ++ ++ /* Lead and tail tabulated values of sinh(i) and cosh(i) ++ for i = 0,...,36. The lead part has 26 leading bits. */ ++ ++ static const double sinh_lead[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.17520117759704589844e+00, /* 0x3ff2cd9fc0000000 */ ++ 3.62686038017272949219e+00, /* 0x400d03cf60000000 */ ++ 1.00178747177124023438e+01, /* 0x40240926e0000000 */ ++ 2.72899169921875000000e+01, /* 0x403b4a3800000000 */ ++ 7.42032089233398437500e+01, /* 0x40528d0160000000 */ ++ 2.01713153839111328125e+02, /* 0x406936d228000000 */ ++ 5.48316116333007812500e+02, /* 0x4081228768000000 */ ++ 1.49047882080078125000e+03, /* 0x409749ea50000000 */ ++ 4.05154187011718750000e+03, /* 0x40afa71570000000 */ ++ 1.10132326660156250000e+04, /* 0x40c5829dc8000000 */ ++ 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ ++ 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ ++ 2.21206695312500000000e+05, /* 0x410b00b590000000 */ ++ 6.01302140625000000000e+05, /* 0x412259ac48000000 */ ++ 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ ++ 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ ++ 1.20774762500000000000e+07, /* 0x4167093488000000 */ ++ 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ ++ 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ ++ 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ ++ 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ ++ 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ ++ 4.87240166400000000000e+09, /* 0x41f226af30000000 */ ++ 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ ++ 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ ++ 9.78648043520000000000e+10, /* 0x4236c93268000000 */ ++ 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ ++ 7.23128516608000000000e+11, /* 0x42650bba30000000 */ ++ 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ ++ 5.34323724288000000000e+12, /* 0x4293704708000000 */ ++ 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ ++ 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ ++ 1.07321789251584000000e+14, /* 0x42d866f348000000 */ ++ 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ ++ 7.93006722514944000000e+14, /* 0x430689e220000000 */ ++ 2.15561576592179200000e+15}; /* 0x431ea215a0000000 */ ++ ++ static const double sinh_tail[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.60467555584448807892e-08, /* 0x3e513ae6096a0092 */ ++ 2.76742892754807136947e-08, /* 0x3e5db70cfb79a640 */ ++ 2.09697499555224576530e-07, /* 0x3e8c2526b66dc067 */ ++ 2.04940252448908240062e-07, /* 0x3e8b81b18647f380 */ ++ 1.65444891522700935932e-06, /* 0x3ebbc1cdd1e1eb08 */ ++ 3.53116789999998198721e-06, /* 0x3ecd9f201534fb09 */ ++ 6.94023870987375490695e-06, /* 0x3edd1c064a4e9954 */ ++ 4.98876893611587449271e-06, /* 0x3ed4eca65d06ea74 */ ++ 3.19656024605152215752e-05, /* 0x3f00c259bcc0ecc5 */ ++ 2.08687768377236501204e-04, /* 0x3f2b5a6647cf9016 */ ++ 4.84668088325403796299e-05, /* 0x3f09691adefb0870 */ ++ 1.17517985422733832468e-03, /* 0x3f53410fc29cde38 */ ++ 6.90830086959560562415e-04, /* 0x3f46a31a50b6fb3c */ ++ 1.45697262451506548420e-03, /* 0x3f57defc71805c40 */ ++ 2.99859023684906737806e-02, /* 0x3f9eb49fd80e0bab */ ++ 1.02538800507941396667e-02, /* 0x3f84fffc7bcd5920 */ ++ 1.26787628407699110022e-01, /* 0x3fc03a93b6c63435 */ ++ 6.86652479544033744752e-02, /* 0x3fb1940bb255fd1c */ ++ 4.81593627621056619148e-01, /* 0x3fded26e14260b50 */ ++ 1.70489513795397629181e+00, /* 0x3ffb47401fc9f2a2 */ ++ 1.12416073482258713767e+01, /* 0x40267bb3f55634f1 */ ++ 7.06579578070110514432e+00, /* 0x401c435ff8194ddc */ ++ 5.91244512999659974639e+01, /* 0x404d8fee052ba63a */ ++ 1.68921736147050694399e+02, /* 0x40651d7edccde3f6 */ ++ 2.60692936262073658327e+02, /* 0x40704b1644557d1a */ ++ 3.62419382134885609048e+02, /* 0x4076a6b5ca0a9dc4 */ ++ 4.07689930834187271103e+03, /* 0x40afd9cc72249aba */ ++ 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ ++ 2.53720210371943067003e+04, /* 0x40d8c70158ac6363 */ ++ 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ ++ 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ ++ 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ ++ 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ ++ 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ ++ 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ ++ 7.63580561355670914054e+06}; /* 0x415d20d76744835c */ ++ ++ static const double cosh_lead[ 37] = { ++ 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ ++ 1.54308062791824340820e+00, /* 0x3ff8b07550000000 */ ++ 3.76219564676284790039e+00, /* 0x400e18fa08000000 */ ++ 1.00676617622375488281e+01, /* 0x402422a490000000 */ ++ 2.73082327842712402344e+01, /* 0x403b4ee858000000 */ ++ 7.42099475860595703125e+01, /* 0x40528d6fc8000000 */ ++ 2.01715633392333984375e+02, /* 0x406936e678000000 */ ++ 5.48317031860351562500e+02, /* 0x4081228948000000 */ ++ 1.49047915649414062500e+03, /* 0x409749eaa8000000 */ ++ 4.05154199218750000000e+03, /* 0x40afa71580000000 */ ++ 1.10132329101562500000e+04, /* 0x40c5829dd0000000 */ ++ 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ ++ 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ ++ 2.21206695312500000000e+05, /* 0x410b00b590000000 */ ++ 6.01302140625000000000e+05, /* 0x412259ac48000000 */ ++ 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ ++ 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ ++ 1.20774762500000000000e+07, /* 0x4167093488000000 */ ++ 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ ++ 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ ++ 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ ++ 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ ++ 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ ++ 4.87240166400000000000e+09, /* 0x41f226af30000000 */ ++ 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ ++ 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ ++ 9.78648043520000000000e+10, /* 0x4236c93268000000 */ ++ 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ ++ 7.23128516608000000000e+11, /* 0x42650bba30000000 */ ++ 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ ++ 5.34323724288000000000e+12, /* 0x4293704708000000 */ ++ 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ ++ 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ ++ 1.07321789251584000000e+14, /* 0x42d866f348000000 */ ++ 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ ++ 7.93006722514944000000e+14, /* 0x430689e220000000 */ ++ 2.15561576592179200000e+15}; /* 0x431ea215a0000000 */ ++ ++ static const double cosh_tail[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 6.89700037027478056904e-09, /* 0x3e3d9f5504c2bd28 */ ++ 4.43207835591715833630e-08, /* 0x3e67cb66f0a4c9fd */ ++ 2.33540217013828929694e-07, /* 0x3e8f58617928e588 */ ++ 5.17452463948269748331e-08, /* 0x3e6bc7d000c38d48 */ ++ 9.38728274131605919153e-07, /* 0x3eaf7f9d4e329998 */ ++ 2.73012191010840495544e-06, /* 0x3ec6e6e464885269 */ ++ 3.29486051438996307950e-06, /* 0x3ecba3a8b946c154 */ ++ 4.75803746362771416375e-06, /* 0x3ed3f4e76110d5a4 */ ++ 3.33050940471947692369e-05, /* 0x3f017622515a3e2b */ ++ 9.94707313972136215365e-06, /* 0x3ee4dc4b528af3d0 */ ++ 6.51685096227860253398e-05, /* 0x3f11156278615e10 */ ++ 1.18132406658066663359e-03, /* 0x3f535ad50ed821f5 */ ++ 6.93090416366541877541e-04, /* 0x3f46b61055f2935c */ ++ 1.45780415323416845386e-03, /* 0x3f57e2794a601240 */ ++ 2.99862082708111758744e-02, /* 0x3f9eb4b45f6aadd3 */ ++ 1.02539925859688602072e-02, /* 0x3f85000b967b3698 */ ++ 1.26787669807076286421e-01, /* 0x3fc03a940fadc092 */ ++ 6.86652631843830962843e-02, /* 0x3fb1940bf3bf874c */ ++ 4.81593633223853068159e-01, /* 0x3fded26e1a2a2110 */ ++ 1.70489514001513020602e+00, /* 0x3ffb4740205796d6 */ ++ 1.12416073489841270572e+01, /* 0x40267bb3f55cb85d */ ++ 7.06579578098005001152e+00, /* 0x401c435ff81e18ac */ ++ 5.91244513000686140458e+01, /* 0x404d8fee052bdea4 */ ++ 1.68921736147088438429e+02, /* 0x40651d7edccde926 */ ++ 2.60692936262087528121e+02, /* 0x40704b1644557e0e */ ++ 3.62419382134890611269e+02, /* 0x4076a6b5ca0a9e1c */ ++ 4.07689930834187453002e+03, /* 0x40afd9cc72249abe */ ++ 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ ++ 2.53720210371943103382e+04, /* 0x40d8c70158ac6364 */ ++ 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ ++ 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ ++ 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ ++ 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ ++ 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ ++ 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ ++ 7.63580561355670914054e+06}; /* 0x415d20d76744835c */ ++ ++ unsigned long ux, aux, xneg; ++ double y, z, z1, z2; ++ int m; ++ ++ /* Special cases */ ++ ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ if (aux < 0x3e30000000000000) /* |x| small enough that cosh(x) = 1 */ ++ { ++ if (aux == 0) ++ /* with no inexact */ ++ return 1.0; ++ else ++ return val_with_flags(1.0, AMD_F_INEXACT); ++ } ++ else if (aux >= PINFBITPATT_DP64) /* |x| is NaN or Inf */ ++ { ++ if (aux > PINFBITPATT_DP64) /* |x| is a NaN? */ ++ return x + x; ++ else /* x is infinity */ ++ return infinity_with_flags(0); ++ } ++ ++ xneg = (aux != ux); ++ ++ y = x; ++ if (xneg) y = -x; ++ ++ if (y >= max_cosh_arg) ++ { ++ /* Return +/-infinity with overflow flag */ ++ return retval_errno_erange(x); ++ } ++ else if (y >= small_threshold) ++ { ++ /* In this range y is large enough so that ++ the negative exponential is negligible, ++ so cosh(y) is approximated by sign(x)*exp(y)/2. The ++ code below is an inlined version of that from ++ exp() with two changes (it operates on ++ y instead of x, and the division by 2 is ++ done by reducing m by 1). */ ++ ++ splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, ++ log2_by_32_tail, &m, &z1, &z2); ++ m -= 1; ++ ++ if (m >= EMIN_DP64 && m <= EMAX_DP64) ++ z = scaleDouble_1((z1+z2),m); ++ else ++ z = scaleDouble_2((z1+z2),m); ++ } ++ else ++ { ++ /* In this range we find the integer part y0 of y ++ and the increment dy = y - y0. We then compute ++ ++ z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) ++ z = cosh(y) = cosh(y0)cosh(dy) + sinh(y0)sinh(dy) ++ ++ where sinh(y0) and cosh(y0) are tabulated above. */ ++ ++ int ind; ++ double dy, dy2, sdy, cdy; ++ ++ ind = (int)y; ++ dy = y - ind; ++ ++ dy2 = dy*dy; ++ sdy = dy*dy2*(0.166666666666666667013899e0 + ++ (0.833333333333329931873097e-2 + ++ (0.198412698413242405162014e-3 + ++ (0.275573191913636406057211e-5 + ++ (0.250521176994133472333666e-7 + ++ (0.160576793121939886190847e-9 + ++ 0.7746188980094184251527126e-12*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ cdy = dy2*(0.500000000000000005911074e0 + ++ (0.416666666666660876512776e-1 + ++ (0.138888888889814854814536e-2 + ++ (0.248015872460622433115785e-4 + ++ (0.275573350756016588011357e-6 + ++ (0.208744349831471353536305e-8 + ++ 0.1163921388172173692062032e-10*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ /* At this point sinh(dy) is approximated by dy + sdy, and cosh(dy) is approximated by 1 + cdy. ++ Shift some significant bits from dy to cdy. */ ++#if 0 ++ double sdy1,sdy2; ++ GET_BITS_DP64(dy, ux); ++ ux &= 0xfffffffff8000000; ++ PUT_BITS_DP64(ux, sdy1); // sdy1 is upper 53-27=26 significant bits of dy. ++ sdy2 = sdy + (dy - sdy1); // sdy2 is sdy + lower bits of dy ++ ++ z = ((((((cosh_tail[ind]*cdy + sinh_tail[ind]*sdy2) ++ + sinh_tail[ind]*sdy1) + cosh_tail[ind]) ++ + cosh_lead[ind]*cdy) + sinh_lead[ind]*sdy2) ++ + sinh_lead[ind]*sdy1) + cosh_lead[ind]; ++#else ++ z = ((((((cosh_tail[ind]*cdy + sinh_tail[ind]*sdy) ++ + sinh_tail[ind]*dy) + cosh_tail[ind]) ++ + cosh_lead[ind]*cdy) + sinh_lead[ind]*sdy) ++ + sinh_lead[ind]*dy) + cosh_lead[ind]; ++#endif ++ } ++ ++ return z; ++} ++ ++weak_alias (__cosh, cosh) +diff -urpN libc/sysdeps/x86_64/fpu/w_coshf.c libc-amd/sysdeps/x86_64/fpu/w_coshf.c +--- libc/sysdeps/x86_64/fpu/w_coshf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_coshf.c 2006-03-22 02:23:58.000000000 +0100 +@@ -0,0 +1,256 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_INFINITYF_WITH_FLAGS ++#define USE_VALF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_INFINITYF_WITH_FLAGS ++#undef USE_VALF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"coshf"; ++ if (_LIB_VERSION == _SVID_) ++ { ++ exc.retval = HUGE; ++ } ++ else ++ { ++ exc.retval = infinityf_with_flags(AMD_F_OVERFLOW); ++ } ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++ ++float __coshf(float fx) ++{ ++ /* ++ After dealing with special cases the computation is split into ++ regions as follows: ++ ++ abs(x) >= max_cosh_arg: ++ cosh(x) = sign(x)*Inf ++ ++ abs(x) >= small_threshold: ++ cosh(x) = sign(x)*exp(abs(x))/2 computed using the ++ splitexp and scaleDouble functions as for exp_amd(). ++ ++ abs(x) < small_threshold: ++ compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) ++ cosh(x) is then sign(x)*z. */ ++ ++ static const double ++ /* The max argument of coshf, but stored as a double */ ++ max_cosh_arg = 8.94159862922329438106e+01, /* 0x40565a9f84f82e63 */ ++ thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ ++ log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ ++ log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ ++ ++ small_threshold = 8*BASEDIGITS_DP64*0.30102999566398119521373889; ++// small_threshold = 20.0; ++ /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ ++ ++ /* Tabulated values of sinh(i) and cosh(i) for i = 0,...,36. */ ++ ++ static const double sinh_lead[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.17520119364380137839e+00, /* 0x3ff2cd9fc44eb982 */ ++ 3.62686040784701857476e+00, /* 0x400d03cf63b6e19f */ ++ 1.00178749274099008204e+01, /* 0x40240926e70949ad */ ++ 2.72899171971277496596e+01, /* 0x403b4a3803703630 */ ++ 7.42032105777887522891e+01, /* 0x40528d0166f07374 */ ++ 2.01713157370279219549e+02, /* 0x406936d22f67c805 */ ++ 5.48316123273246489589e+02, /* 0x408122876ba380c9 */ ++ 1.49047882578955000099e+03, /* 0x409749ea514eca65 */ ++ 4.05154190208278987484e+03, /* 0x40afa7157430966f */ ++ 1.10132328747033916443e+04, /* 0x40c5829dced69991 */ ++ 2.99370708492480553105e+04, /* 0x40dd3c4488cb48d6 */ ++ 8.13773957064298447222e+04, /* 0x40f3de1654d043f0 */ ++ 2.21206696003330085659e+05, /* 0x410b00b5916a31a5 */ ++ 6.01302142081972560845e+05, /* 0x412259ac48bef7e3 */ ++ 1.63450868623590236530e+06, /* 0x4138f0ccafad27f6 */ ++ 4.44305526025387924165e+06, /* 0x4150f2ebd0a7ffe3 */ ++ 1.20774763767876271158e+07, /* 0x416709348c0ea4ed */ ++ 3.28299845686652474105e+07, /* 0x417f4f22091940bb */ ++ 8.92411504815936237574e+07, /* 0x419546d8f9ed26e1 */ ++ 2.42582597704895108938e+08, /* 0x41aceb088b68e803 */ ++ 6.59407867241607308388e+08, /* 0x41c3a6e1fd9eecfd */ ++ 1.79245642306579566002e+09, /* 0x41dab5adb9c435ff */ ++ 4.87240172312445068359e+09, /* 0x41f226af33b1fdc0 */ ++ 1.32445610649217357635e+10, /* 0x4208ab7fb5475fb7 */ ++ 3.60024496686929321289e+10, /* 0x4220c3d3920962c8 */ ++ 9.78648047144193725586e+10, /* 0x4236c932696a6b5c */ ++ 2.66024120300899291992e+11, /* 0x424ef822f7f6731c */ ++ 7.23128532145737548828e+11, /* 0x42650bba3796379a */ ++ 1.96566714857202099609e+12, /* 0x427c9aae4631c056 */ ++ 5.34323729076223046875e+12, /* 0x429370470aec28ec */ ++ 1.45244248326237109375e+13, /* 0x42aa6b765d8cdf6c */ ++ 3.94814800913403437500e+13, /* 0x42c1f43fcc4b662c */ ++ 1.07321789892958031250e+14, /* 0x42d866f34a725782 */ ++ 2.91730871263727437500e+14, /* 0x42f0953e2f3a1ef7 */ ++ 7.93006726156715250000e+14, /* 0x430689e221bc8d5a */ ++ 2.15561577355759750000e+15}; /* 0x431ea215a1d20d76 */ ++ ++ static const double cosh_lead[ 37] = { ++ 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ ++ 1.54308063481524371241e+00, /* 0x3ff8b07551d9f550 */ ++ 3.76219569108363138810e+00, /* 0x400e18fa0df2d9bc */ ++ 1.00676619957777653269e+01, /* 0x402422a497d6185e */ ++ 2.73082328360164865444e+01, /* 0x403b4ee858de3e80 */ ++ 7.42099485247878334349e+01, /* 0x40528d6fcbeff3a9 */ ++ 2.01715636122455890700e+02, /* 0x406936e67db9b919 */ ++ 5.48317035155212010977e+02, /* 0x4081228949ba3a8b */ ++ 1.49047916125217807348e+03, /* 0x409749eaa93f4e76 */ ++ 4.05154202549259389343e+03, /* 0x40afa715845d8894 */ ++ 1.10132329201033226127e+04, /* 0x40c5829dd053712d */ ++ 2.99370708659497577173e+04, /* 0x40dd3c4489115627 */ ++ 8.13773957125740562333e+04, /* 0x40f3de1654d6b543 */ ++ 2.21206696005590405548e+05, /* 0x410b00b5916b6105 */ ++ 6.01302142082804115489e+05, /* 0x412259ac48bf13ca */ ++ 1.63450868623620807193e+06, /* 0x4138f0ccafad2d17 */ ++ 4.44305526025399193168e+06, /* 0x4150f2ebd0a8005c */ ++ 1.20774763767876680940e+07, /* 0x416709348c0ea503 */ ++ 3.28299845686652623117e+07, /* 0x417f4f22091940bf */ ++ 8.92411504815936237574e+07, /* 0x419546d8f9ed26e1 */ ++ 2.42582597704895138741e+08, /* 0x41aceb088b68e804 */ ++ 6.59407867241607308388e+08, /* 0x41c3a6e1fd9eecfd */ ++ 1.79245642306579566002e+09, /* 0x41dab5adb9c435ff */ ++ 4.87240172312445068359e+09, /* 0x41f226af33b1fdc0 */ ++ 1.32445610649217357635e+10, /* 0x4208ab7fb5475fb7 */ ++ 3.60024496686929321289e+10, /* 0x4220c3d3920962c8 */ ++ 9.78648047144193725586e+10, /* 0x4236c932696a6b5c */ ++ 2.66024120300899291992e+11, /* 0x424ef822f7f6731c */ ++ 7.23128532145737548828e+11, /* 0x42650bba3796379a */ ++ 1.96566714857202099609e+12, /* 0x427c9aae4631c056 */ ++ 5.34323729076223046875e+12, /* 0x429370470aec28ec */ ++ 1.45244248326237109375e+13, /* 0x42aa6b765d8cdf6c */ ++ 3.94814800913403437500e+13, /* 0x42c1f43fcc4b662c */ ++ 1.07321789892958031250e+14, /* 0x42d866f34a725782 */ ++ 2.91730871263727437500e+14, /* 0x42f0953e2f3a1ef7 */ ++ 7.93006726156715250000e+14, /* 0x430689e221bc8d5a */ ++ 2.15561577355759750000e+15}; /* 0x431ea215a1d20d76 */ ++ ++ unsigned long ux, aux, xneg; ++ double x = fx, y, z, z1, z2; ++ int m; ++ ++ /* Special cases */ ++ ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ if (aux < 0x3f10000000000000) /* |x| small enough that cosh(x) = 1 */ ++ { ++ if (aux == 0) return (float)1.0; /* with no inexact */ ++ else return valf_with_flags((float)1.0, AMD_F_INEXACT); /* with inexact */ ++ } ++ else if (aux >= PINFBITPATT_DP64) /* |x| is NaN or Inf */ ++ { ++ if (aux > PINFBITPATT_DP64) /* |x| is a NaN? */ ++ return fx + fx; ++ else /* x is infinity */ ++ return infinityf_with_flags(0); ++ } ++ ++ xneg = (aux != ux); ++ ++ y = x; ++ if (xneg) y = -x; ++ ++ if (y >= max_cosh_arg) ++ { ++ /* Return infinity with overflow flag. */ ++#if 0 ++ /* This way handles non-POSIX behaviour but weirdly causes ++ sinhf to run half as fast for all arguments on Hammer */ ++ return retval_errno_erange(fx); ++#else ++ /* This handles POSIX behaviour */ ++ __set_errno(ERANGE); ++ z = infinityf_with_flags(AMD_F_OVERFLOW); ++#endif ++ } ++ else if (y >= small_threshold) ++ { ++ /* In this range y is large enough so that ++ the negative exponential is negligible, ++ so cosh(y) is approximated by sign(x)*exp(y)/2. The ++ code below is an inlined version of that from ++ exp() with two changes (it operates on ++ y instead of x, and the division by 2 is ++ done by reducing m by 1). */ ++ ++ splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, ++ log2_by_32_tail, &m, &z1, &z2); ++ m -= 1; ++ /* scaleDouble_1 is always safe because the argument x was ++ float, rather than double */ ++ ++ z = scaleDouble_1((z1+z2),m); ++ } ++ else ++ { ++ /* In this range we find the integer part y0 of y ++ and the increment dy = y - y0. We then compute ++ ++ z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) ++ z = cosh(y) = cosh(y0)cosh(dy) + sinh(y0)sinh(dy) ++ ++ where sinh(y0) and cosh(y0) are tabulated above. */ ++ ++ int ind; ++ double dy, dy2, sdy, cdy; ++ ++ ind = (int)y; ++ dy = y - ind; ++ ++ dy2 = dy*dy; ++ ++ sdy = dy + dy*dy2*(0.166666666666666667013899e0 + ++ (0.833333333333329931873097e-2 + ++ (0.198412698413242405162014e-3 + ++ (0.275573191913636406057211e-5 + ++ (0.250521176994133472333666e-7 + ++ (0.160576793121939886190847e-9 + ++ 0.7746188980094184251527126e-12*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ cdy = 1 + dy2*(0.500000000000000005911074e0 + ++ (0.416666666666660876512776e-1 + ++ (0.138888888889814854814536e-2 + ++ (0.248015872460622433115785e-4 + ++ (0.275573350756016588011357e-6 + ++ (0.208744349831471353536305e-8 + ++ 0.1163921388172173692062032e-10*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ z = cosh_lead[ind]*cdy + sinh_lead[ind]*sdy; ++ } ++ ++// if (xneg) z = - z; ++ return (float)z; ++} ++ ++weak_alias (__coshf, coshf) +diff -urpN libc/sysdeps/x86_64/fpu/w_exp10.c libc-amd/sysdeps/x86_64/fpu/w_exp10.c +--- libc/sysdeps/x86_64/fpu/w_exp10.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_exp10.c 2006-03-22 02:24:45.000000000 +0100 +@@ -0,0 +1,161 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_ZERO_WITH_FLAGS ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_ZERO_WITH_FLAGS ++#undef USE_INFINITY_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange_overflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"exp10"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline double retval_errno_erange_underflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"exp10"; ++ exc.retval = zero_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++double __exp10(double x) ++{ ++ static const double ++ max_exp10_arg = 3.0825471555991674677e+02, /* 0x40734413509f79ff */ ++ min_exp10_arg = -3.2330621534311580944e+02, /* 0xc07434e6420f4374 */ ++ log10 = 2.30258509299404568401e+00, /* 0x40026bb1bbb55516 */ ++ thirtytwo_by_log10of2 = 1.06301699036395595131e+02, /* 0x405a934f0979a371 */ ++ log10of2_by_32_lead = 9.40718688070774078369e-03, /* 0x3F83441340000000 */ ++ log10of2_by_32_trail = 4.83791671566737916758e-10; /* 0x3E009F79FEF311F1 */ ++ ++ double y, z1, z2, z; ++ int m; ++ unsigned long ux, ax; ++ ++ /* ++ Computation of exp10(x). ++ ++ We compute the values m, z1, and z2 such that ++ exp10(x) = 2**m * (z1 + z2), where exp10(x) is 10**x. ++ ++ Computations needed in order to obtain m, z1, and z2 ++ involve three steps. ++ ++ First, we reduce the argument x to the form ++ x = n * log10of2/32 + remainder, ++ where n has the value of an integer and |remainder| <= log10of2/64. ++ The value of n = x * 32/log10of2 rounded to the nearest integer and ++ the remainder = x - n*log10of2/32. ++ ++ Second, we approximate exp10(r1 + r2) - 1 where r1 is the leading ++ part of the remainder and r2 is the trailing part of the remainder. ++ ++ Third, we reconstruct exp10(x) so that ++ exp10(x) = 2**m * (z1 + z2). ++ */ ++ ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ if (ax >= 0x40734413509f79ff) /* abs(x) >= 308.25... */ ++ { ++ if(ax >= 0x7ff0000000000000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_DP64) ++ /* x is negative infinity; return 0.0 with no flags. */ ++ return 0.0; ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ if (x > max_exp10_arg) ++ /* Return +infinity with overflow flag */ ++ return retval_errno_erange_overflow(x); ++ else if (x < min_exp10_arg) ++ /* x is negative. Return +zero with underflow and inexact flags */ ++ return retval_errno_erange_underflow(x); ++ } ++ ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3f9bcb7b131bbb9d) /* abs(x) < 1/(16*log10) */ ++ { ++ if (ax < 0x3c00000000000000) /* abs(x) < 2^(-63) */ ++ return 1.0 + x; /* Raises inexact if x is non-zero */ ++ else ++ y = log10*x; ++ z = (((((((((( ++ 1.0/3628800)*y+ ++ 1.0/362880)*y+ ++ 1.0/40320)*y+ ++ 1.0/5040)*y+ ++ 1.0/720)*y+ ++ 1.0/120)*y+ ++ 1.0/24)*y+ ++ 1.0/6)*y+ ++ 1.0/2)*y+ ++ 1.0)*y + 1.0; ++ } ++ else ++ { ++ /* Find m, z1 and z2 such that exp10(x) = 2**m * (z1 + z2) */ ++ ++ splitexp(x, log10, thirtytwo_by_log10of2, log10of2_by_32_lead, ++ log10of2_by_32_trail, &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**m */ ++ if (m > EMIN_DP64 && m < EMAX_DP64) ++ return scaleDouble_1((z1+z2),m); ++ else ++ return scaleDouble_2((z1+z2),m); ++ } ++ return z; ++} ++ ++weak_alias (__exp10, exp10) ++strong_alias (__exp10, __pow10) ++weak_alias (__pow10, pow10) +diff -urpN libc/sysdeps/x86_64/fpu/w_exp10f.c libc-amd/sysdeps/x86_64/fpu/w_exp10f.c +--- libc/sysdeps/x86_64/fpu/w_exp10f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_exp10f.c 2006-03-22 02:25:09.000000000 +0100 +@@ -0,0 +1,158 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXPF ++#define USE_SCALEFLOAT_1 ++#define USE_SCALEFLOAT_2 ++#define USE_ZEROF_WITH_FLAGS ++#define USE_INFINITYF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXPF ++#undef USE_SCALEFLOAT_1 ++#undef USE_SCALEFLOAT_2 ++#undef USE_ZEROF_WITH_FLAGS ++#undef USE_INFINITYF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange_overflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"exp10f"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinityf_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline float retval_errno_erange_underflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"exp10f"; ++ exc.retval = zerof_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++float __exp10f(float x) ++{ ++ static const float ++ max_exp10_arg = 3.8531841278E+01F, /* 0x421A209B */ ++ min_exp10_arg =-4.4853469848E+01F, /* 0xC23369F4 */ ++ log10 = 2.3025850929E+00F, /* 0x40135D8E */ ++ thirtytwo_by_log10of2 = 1.0630169677E+02F, /* 0x42D49A78 */ ++ log10of2_by_32_lead = 9.4070434570E-03F, /* 0x3C1A2000 */ ++ log10of2_by_32_tail = 1.4390730030E-07F; /* 0x341A84F0 */ ++ ++ float y, z1, z2, z; ++ int m; ++ unsigned int ux, ax; ++ ++ /* ++ Computation of exp10f (x). ++ ++ We compute the values m, z1, and z2 such that ++ exp10f(x) = 2**m * (z1 + z2), where exp10f(x) is 10**x. ++ ++ Computations needed in order to obtain m, z1, and z2 ++ involve three steps. ++ ++ First, we reduce the argument x to the form ++ x = n * log10of2/32 + remainder, ++ where n has the value of an integer and |remainder| <= log10of2/64. ++ The value of n = x * 32/log10of2 rounded to the nearest integer and ++ the remainder = x - n*log10of2/32. ++ ++ Second, we approximate exp10f(r1 + r2) - 1 where r1 is the leading ++ part of the remainder and r2 is the trailing part of the remainder. ++ ++ Third, we reconstruct exp10f(x) so that ++ exp10f(x) = 2**m * (z1 + z2). ++ */ ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ ++ if (ax >= 0x421A209B) /* abs(x) >= 38.5... */ ++ { ++ if(ax >= 0x7f800000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_SP32) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_SP32) ++ /* x is negative infinity; return 0.0 with no flags. */ ++ return 0.0F; ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ if (x > max_exp10_arg) ++ /* Return +infinity with overflow flag */ ++ return retval_errno_erange_overflow(x); ++ else if (x < min_exp10_arg) ++ /* x is negative. Return +zero with underflow and inexact flags */ ++ return retval_errno_erange_underflow(x); ++ } ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3bde5bd9) /* abs(x) < 1/(64*log10) */ ++ { ++ if (ax < 0x32800000) /* abs(x) < 2^(-26) */ ++ return 1.0F + x; /* Raises inexact if x is non-zero */ ++ else ++ y = log10*x; ++ z = (((((((( ++ 1.0F/40320)*x+ ++ 1.0F/5040)*y+ ++ 1.0F/720)*y+ ++ 1.0F/120)*y+ ++ 1.0F/24)*y+ ++ 1.0F/6)*y+ ++ 1.0F/2)*y+ ++ 1.0F)*y + 1.0; ++ } ++ else ++ { ++ /* Find m, z1 and z2 such that exp10f(x) = 2**m * (z1 + z2) */ ++ ++ splitexpf(x, log10, thirtytwo_by_log10of2, log10of2_by_32_lead, ++ log10of2_by_32_tail, &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**m */ ++ ++ if (m >= EMIN_SP32 && m <= EMAX_SP32) ++ z = scaleFloat_1((z1+z2),m); ++ else ++ z = scaleFloat_2((z1+z2),m); ++ } ++ return z; ++} ++ ++weak_alias (__exp10f, exp10f) ++strong_alias (__exp10f, __pow10f) ++weak_alias (__pow10f, pow10f) +diff -urpN libc/sysdeps/x86_64/fpu/w_exp2.c libc-amd/sysdeps/x86_64/fpu/w_exp2.c +--- libc/sysdeps/x86_64/fpu/w_exp2.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_exp2.c 2006-03-22 02:25:32.000000000 +0100 +@@ -0,0 +1,173 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_ZERO_WITH_FLAGS ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_ZERO_WITH_FLAGS ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_INFINITY_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange_overflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"exp2"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline double retval_errno_erange_underflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"exp2"; ++ exc.retval = zero_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++double __exp2(double x) ++{ ++ static const double ++ max_exp2_arg = 1024.0, /* 0x4090000000000000 */ ++ min_exp2_arg = -1074.0, /* 0xc090c80000000000 */ ++ log2 = 6.931471805599453094178e-01, /* 0x3fe62e42fefa39ef */ ++ log2_lead = 6.93147167563438415527E-01, /* 0x3fe62e42f8000000 */ ++ log2_tail = 1.29965068938898869640E-08, /* 0x3e4be8e7bcd5e4f1 */ ++ one_by_32_lead = 0.03125; ++ ++ double y, z1, z2, z, hx, tx, y1, y2; ++ int m; ++ unsigned long ux, ax; ++ ++ /* ++ Computation of exp2(x). ++ ++ We compute the values m, z1, and z2 such that ++ exp2(x) = 2**m * (z1 + z2), where exp2(x) is 2**x. ++ ++ Computations needed in order to obtain m, z1, and z2 ++ involve three steps. ++ ++ First, we reduce the argument x to the form ++ x = n/32 + remainder, ++ where n has the value of an integer and |remainder| <= 1/64. ++ The value of n = x * 32 rounded to the nearest integer and ++ the remainder = x - n/32. ++ ++ Second, we approximate exp2(r1 + r2) - 1 where r1 is the leading ++ part of the remainder and r2 is the trailing part of the remainder. ++ ++ Third, we reconstruct exp2(x) so that ++ exp2(x) = 2**m * (z1 + z2). ++ */ ++ ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ if (ax >= 0x4090000000000000) /* abs(x) >= 1024.0 */ ++ { ++ if(ax >= 0x7ff0000000000000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_DP64) ++ /* x is negative infinity; return 0.0 with no flags. */ ++ return 0.0; ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ if (x > max_exp2_arg) ++ /* Return +infinity with overflow flag */ ++ return retval_errno_erange_overflow(x); ++ else if (x < min_exp2_arg) ++ /* x is negative. Return +zero with underflow and inexact flags */ ++ return retval_errno_erange_underflow(x); ++ } ++ ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3fb7154764ee6c2f) /* abs(x) < 1/(16*log2) */ ++ { ++ if (ax < 0x3c00000000000000) /* abs(x) < 2^(-63) */ ++ return 1.0 + x; /* Raises inexact if x is non-zero */ ++ else ++ { ++ /* Split x into hx (head) and tx (tail). */ ++ unsigned long u; ++ hx = x; ++ GET_BITS_DP64(hx, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hx); ++ tx = x - hx; ++ /* Carefully multiply x by log2. y1 is the most significant ++ part of the result, and y2 the least significant part */ ++ y1 = x * log2_lead; ++ y2 = (((hx * log2_lead - y1) + hx * log2_tail) + ++ tx * log2_lead) + tx * log2_tail; ++ ++ y = y1 + y2; ++ z = (9.99564649780173690e-1 + ++ (1.61251249355268050e-5 + ++ (2.37986978239838493e-2 + ++ 2.68724774856111190e-7*y)*y)*y)/ ++ (9.99564649780173692e-1 + ++ (-4.99766199765151309e-1 + ++ (1.070876894098586184e-1 + ++ (-1.189773642681502232e-2 + ++ 5.9480622371960190616e-4*y)*y)*y)*y); ++ z = ((z * y1) + (z * y2)) + 1.0; ++ } ++ } ++ else ++ { ++ /* Find m, z1 and z2 such that exp2(x) = 2**m * (z1 + z2) */ ++ ++ splitexp(x, log2, 32.0, one_by_32_lead, 0.0, &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**m */ ++ if (m > EMIN_DP64 && m < EMAX_DP64) ++ z = scaleDouble_1((z1+z2),m); ++ else ++ z = scaleDouble_2((z1+z2),m); ++ } ++ return z; ++} ++ ++weak_alias (__exp2, exp2) ++weak_alias (__exp2, __libm_ieee754_exp2) +diff -urpN libc/sysdeps/x86_64/fpu/w_exp2f.c libc-amd/sysdeps/x86_64/fpu/w_exp2f.c +--- libc/sysdeps/x86_64/fpu/w_exp2f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_exp2f.c 2006-03-22 02:27:52.000000000 +0100 +@@ -0,0 +1,156 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXPF ++#define USE_SCALEFLOAT_1 ++#define USE_SCALEFLOAT_2 ++#define USE_INFINITYF_WITH_FLAGS ++#define USE_ZEROF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXPF ++#undef USE_SCALEFLOAT_1 ++#undef USE_SCALEFLOAT_2 ++#undef USE_INFINITYF_WITH_FLAGS ++#undef USE_ZEROF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange_overflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"exp2f"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinityf_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline float retval_errno_erange_underflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"exp2f"; ++ exc.retval = zerof_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++float __exp2f(float x) ++{ ++ static const float ++ max_exp2_arg = 128.0F, /* 0x43000000 */ ++ min_exp2_arg = -149.0F, /* 0xc3150000 */ ++ log2 = 6.931471824645996e-01F, /* 0x3f317218 */ ++ one_by_32_lead = 0.03125F; ++ ++ float y, z1, z2, z; ++ int m; ++ unsigned int ux, ax; ++ ++ /* ++ Computation of exp2f(x). ++ ++ We compute the values m, z1, and z2 such that ++ exp2f(x) = 2**m * (z1 + z2), where exp2f(x) is 2**x. ++ ++ Computations needed in order to obtain m, z1, and z2 ++ involve three steps. ++ ++ First, we reduce the argument x to the form ++ x = n/32 + remainder, ++ where n has the value of an integer and |remainder| <= 1/64. ++ The value of n = x * 32 rounded to the nearest integer and ++ the remainder = x - n/32. ++ ++ Second, we approximate exp2f(r1 + r2) - 1 where r1 is the leading ++ part of the remainder and r2 is the trailing part of the remainder. ++ ++ Third, we reconstruct exp2f(x) so that ++ exp2f(x) = 2**m * (z1 + z2). ++ */ ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ ++ if (ax >= 0x43000000) /* abs(x) >= 128.0 */ ++ { ++ if(ax >= 0x7f800000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_SP32) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_SP32) ++ /* x is negative infinity; return 0.0 with no flags. */ ++ return 0.0F; ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ if (x > max_exp2_arg) ++ /* Return +infinity with overflow flag */ ++ return retval_errno_erange_overflow(x); ++ else if (x < min_exp2_arg) ++ /* x is negative. Return +zero with underflow and inexact flags */ ++ return retval_errno_erange_underflow(x); ++ } ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3cb8aa3b) /* abs(x) < 1/(64*log2) */ ++ { ++ if (ax < 0x32800000) /* abs(x) < 2^(-26) */ ++ return 1.0F + x; /* Raises inexact if x is non-zero */ ++ else ++ { ++ y = log2*x; ++ z = (((((((( ++ 1.0F/40320)*y+ ++ 1.0F/5040)*y+ ++ 1.0F/720)*y+ ++ 1.0F/120)*y+ ++ 1.0F/24)*y+ ++ 1.0F/6)*y+ ++ 1.0F/2)*y+ ++ 1.0F)*y + 1.0; ++ } ++ } ++ else ++ { ++ /* Find m, z1 and z2 such that exp2f(x) = 2**m * (z1 + z2) */ ++ ++ splitexpf(x, log2, 32.0F, one_by_32_lead, 0.0F, &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**m */ ++ ++ if (m >= EMIN_SP32 && m <= EMAX_SP32) ++ z = scaleFloat_1((z1+z2),m); ++ else ++ z = scaleFloat_2((z1+z2),m); ++ } ++ return z; ++} ++ ++weak_alias (__exp2f, exp2f) ++weak_alias (__exp2f, __libm_ieee754_exp2f) +diff -urpN libc/sysdeps/x86_64/fpu/w_exp.c libc-amd/sysdeps/x86_64/fpu/w_exp.c +--- libc/sysdeps/x86_64/fpu/w_exp.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_exp.c 2006-03-22 02:28:12.000000000 +0100 +@@ -0,0 +1,160 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_ZERO_WITH_FLAGS ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_ZERO_WITH_FLAGS ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_INFINITY_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange_overflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"exp"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline double retval_errno_erange_underflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"exp"; ++ exc.retval = zero_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++double __exp(double x) ++{ ++ static const double ++ max_exp_arg = 7.09782712893383973096e+02, /* 0x40862e42fefa39ef */ ++ min_exp_arg = -7.45133219101941108420e+02, /* 0xc0874910d52d3051 */ ++ thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ ++ log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ ++ log2_by_32_trail = 5.68948749532545630390e-11; /* 0x3dcf473de6af278e */ ++ ++ double z1, z2, z; ++ int m; ++ unsigned long ux, ax; ++ ++ /* ++ Computation of exp(x). ++ ++ We compute the values m, z1, and z2 such that ++ exp(x) = 2**m * (z1 + z2), where ++ exp(x) is the natural exponential of x. ++ ++ Computations needed in order to obtain m, z1, and z2 ++ involve three steps. ++ ++ First, we reduce the argument x to the form ++ x = n * log2/32 + remainder, ++ where n has the value of an integer and |remainder| <= log2/64. ++ The value of n = x * 32/log2 rounded to the nearest integer and ++ the remainder = x - n*log2/32. ++ ++ Second, we approximate exp(r1 + r2) - 1 where r1 is the leading ++ part of the remainder and r2 is the trailing part of the remainder. ++ ++ Third, we reconstruct the exponential of x so that ++ exp(x) = 2**m * (z1 + z2). ++ */ ++ ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ if (ax >= 0x40862e42fefa39ef) /* abs(x) >= 709.78... */ ++ { ++ if(ax >= 0x7ff0000000000000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_DP64) ++ /* x is negative infinity; return 0.0 with no flags. */ ++ return 0.0; ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ if (x > max_exp_arg) ++ /* Return +infinity with overflow flag */ ++ return retval_errno_erange_overflow(x); ++ else if (x < min_exp_arg) ++ /* x is negative. Return +zero with underflow and inexact flags */ ++ return retval_errno_erange_underflow(x); ++ } ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3fb0000000000000) /* abs(x) < 1/16 */ ++ { ++ if (ax < 0x3c00000000000000) /* abs(x) < 2^(-63) */ ++ z = 1.0 + x; /* Raises inexact if x is non-zero */ ++ else ++ z = (((((((((( ++ 1.0/3628800)*x+ ++ 1.0/362880)*x+ ++ 1.0/40320)*x+ ++ 1.0/5040)*x+ ++ 1.0/720)*x+ ++ 1.0/120)*x+ ++ 1.0/24)*x+ ++ 1.0/6)*x+ ++ 1.0/2)*x+ ++ 1.0)*x + 1.0; ++ } ++ else ++ { ++ /* Find m, z1 and z2 such that exp(x) = 2**m * (z1 + z2) */ ++ ++ splitexp(x, 1.0, thirtytwo_by_log2, log2_by_32_lead, log2_by_32_trail, ++ &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**m */ ++ ++ if (m >= EMIN_DP64 && m <= EMAX_DP64) ++ z = scaleDouble_1((z1+z2),m); ++ else ++ z = scaleDouble_2((z1+z2),m); ++ } ++ return z; ++} ++ ++ ++weak_alias (__exp, __ieee754_exp) ++weak_alias (__exp, exp) +diff -urpN libc/sysdeps/x86_64/fpu/w_expf.c libc-amd/sysdeps/x86_64/fpu/w_expf.c +--- libc/sysdeps/x86_64/fpu/w_expf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_expf.c 2006-03-22 02:28:29.000000000 +0100 +@@ -0,0 +1,155 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXPF ++#define USE_SCALEFLOAT_1 ++#define USE_SCALEFLOAT_2 ++#define USE_ZEROF_WITH_FLAGS ++#define USE_INFINITYF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXPF ++#undef USE_SCALEFLOAT_1 ++#undef USE_SCALEFLOAT_2 ++#undef USE_ZEROF_WITH_FLAGS ++#undef USE_INFINITYF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange_overflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"expf"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinityf_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline float retval_errno_erange_underflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"expf"; ++ exc.retval = zerof_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++float __expf(float x) ++{ ++ static const float ++ max_exp_arg = 8.8722839355E+01, /* 0x42B17218 */ ++ min_exp_arg = -1.0327893066E+02, /* 0xC2CE8ED0 */ ++ thirtytwo_by_log2 = 4.6166240692E+01, /* 0x4238AA3B */ ++ log2_by_32_lead = 2.1659851074E-02, /* 0x3CB17000 */ ++ log2_by_32_tail = 9.9831822808E-07; /* 0x3585FDF4 */ ++ ++ float z1, z2, z; ++ int m; ++ unsigned int ux, ax; ++ ++ /* ++ Computation of exp(x). ++ ++ We compute the values m, z1, and z2 such that ++ exp(x) = 2**m * (z1 + z2), where ++ exp(x) is the natural exponential of x. ++ ++ Computations needed in order to obtain m, z1, and z2 ++ involve three steps. ++ ++ First, we reduce the argument x to the form ++ x = n * log2/32 + remainder, ++ where n has the value of an integer and |remainder| <= log2/64. ++ The value of n = x * 32/log2 rounded to the nearest integer and ++ the remainder = x - n*log2/32. ++ ++ Second, we approximate exp(r1 + r2) - 1 where r1 is the leading ++ part of the remainder and r2 is the trailing part of the remainder. ++ ++ Third, we reconstruct the exponential of x so that ++ exp(x) = 2**m * (z1 + z2). ++ */ ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ ++ if (ax >= 0x42B17218) /* abs(x) >= 88.7... */ ++ { ++ if(ax >= 0x7f800000) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_SP32) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else if (ux & SIGNBIT_SP32) ++ /* x is negative infinity; return 0.0 with no flags */ ++ return 0.0; ++ else ++ /* x is positive infinity */ ++ return x; ++ } ++ if (x > max_exp_arg) ++ /* Return +infinity with overflow flag */ ++ return retval_errno_erange_overflow(x); ++ else if (x < min_exp_arg) ++ /* x is negative. Return +zero with underflow and inexact flags */ ++ return retval_errno_erange_underflow(x); ++ } ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3c800000) /* abs(x) < 1/64 */ ++ { ++ if (ax < 0x32800000) /* abs(x) < 2^(-26) */ ++ return 1.0 + x; /* Raises inexact if x is non-zero */ ++ else ++ z = ((((((( ++ 1.0/5040)*x+ ++ 1.0/720)*x+ ++ 1.0/120)*x+ ++ 1.0/24)*x+ ++ 1.0/6)*x+ ++ 1.0/2)*x+ ++ 1.0)*x + 1.0; ++ } ++ else ++ { ++ /* Find m and z such that exp(x) = 2**m * (z1 + z2) */ ++ ++ splitexpf(x, 1.0, thirtytwo_by_log2, log2_by_32_lead, ++ log2_by_32_tail, &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**m */ ++ ++ if (m >= EMIN_SP32 && m <= EMAX_SP32) ++ z = scaleFloat_1((z1+z2),m); ++ else ++ z = scaleFloat_2((z1+z2),m); ++ } ++ return z; ++} ++ ++weak_alias (__expf, expf) ++weak_alias (__expf, __ieee754_expf) +diff -urpN libc/sysdeps/x86_64/fpu/w_fmod.c libc-amd/sysdeps/x86_64/fpu/w_fmod.c +--- libc/sysdeps/x86_64/fpu/w_fmod.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_fmod.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,2 @@ ++#define COMPILING_FMOD ++#include <w_remainder.c> +diff -urpN libc/sysdeps/x86_64/fpu/w_fmodf.c libc-amd/sysdeps/x86_64/fpu/w_fmodf.c +--- libc/sysdeps/x86_64/fpu/w_fmodf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_fmodf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,2 @@ ++#define COMPILING_FMOD ++#include <w_remainderf.c> +diff -urpN libc/sysdeps/x86_64/fpu/w_hypot.c libc-amd/sysdeps/x86_64/fpu/w_hypot.c +--- libc/sysdeps/x86_64/fpu/w_hypot.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_hypot.c 2006-03-22 02:28:51.000000000 +0100 +@@ -0,0 +1,191 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SCALEDOUBLE_1 ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SCALEDOUBLE_1 ++#undef USE_INFINITY_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange_overflow(double x, double y) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = y; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"hypot"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++double __hypot(double x, double y) ++{ ++ /* Returns sqrt(x*x + y*y) with no overflow or underflow unless ++ the result warrants it */ ++ ++ const double large = 1.79769313486231570815e+308; /* 0x7fefffffffffffff */ ++ ++ double u, r, retval, hx, tx, x2, hy, ty, y2, hs, ts; ++ unsigned long xexp, yexp, ux, uy, ut; ++ int dexp, expadjust; ++ ++ GET_BITS_DP64(x, ux); ++ ux &= ~SIGNBIT_DP64; ++ GET_BITS_DP64(y, uy); ++ uy &= ~SIGNBIT_DP64; ++ xexp = (ux >> EXPSHIFTBITS_DP64); ++ yexp = (uy >> EXPSHIFTBITS_DP64); ++ ++ if (xexp == BIASEDEMAX_DP64 + 1 || yexp == BIASEDEMAX_DP64 + 1) ++ { ++ /* One or both of the arguments are NaN or infinity. The ++ result will also be NaN or infinity. */ ++ retval = x*x + y*y; ++ if (((xexp == BIASEDEMAX_DP64 + 1) && !(ux & MANTBITS_DP64)) || ++ ((yexp == BIASEDEMAX_DP64 + 1) && !(uy & MANTBITS_DP64))) ++ /* x or y is infinity. ISO C99 defines that we must ++ return +infinity, even if the other argument is NaN. ++ Note that the computation of x*x + y*y above will already ++ have raised invalid if either x or y is a signalling NaN. */ ++ return infinity_with_flags(0); ++ else ++ /* One or both of x or y is NaN, and neither is infinity. ++ Raise invalid if it's a signalling NaN */ ++ return retval; ++ } ++ ++ /* Set x = abs(x) and y = abs(y) */ ++ PUT_BITS_DP64(ux, x); ++ PUT_BITS_DP64(uy, y); ++ ++ /* The difference in exponents between x and y */ ++ dexp = xexp - yexp; ++ expadjust = 0; ++ ++ if (ux == 0) ++ /* x is zero */ ++ return y; ++ else if (uy == 0) ++ /* y is zero */ ++ return x; ++ else if (dexp > MANTLENGTH_DP64 + 1 || dexp < -MANTLENGTH_DP64 - 1) ++ /* One of x and y is insignificant compared to the other */ ++ return x + y; /* Raise inexact */ ++ else if (xexp > EXPBIAS_DP64 + 500 || yexp > EXPBIAS_DP64 + 500) ++ { ++ /* Danger of overflow; scale down by 2**600. */ ++ expadjust = 600; ++ ux -= 0x2580000000000000; ++ PUT_BITS_DP64(ux, x); ++ uy -= 0x2580000000000000; ++ PUT_BITS_DP64(uy, y); ++ } ++ else if (xexp < EXPBIAS_DP64 - 500 || yexp < EXPBIAS_DP64 - 500) ++ { ++ /* Danger of underflow; scale up by 2**600. */ ++ expadjust = -600; ++ if (xexp == 0) ++ { ++ /* x is denormal - handle by adding 601 to the exponent ++ and then subtracting a correction for the implicit bit */ ++ PUT_BITS_DP64(ux + 0x2590000000000000, x); ++ x -= 9.23297861778573578076e-128; /* 0x2590000000000000 */ ++ GET_BITS_DP64(x, ux); ++ } ++ else ++ { ++ /* x is normal - just increase the exponent by 600 */ ++ ux += 0x2580000000000000; ++ PUT_BITS_DP64(ux, x); ++ } ++ if (yexp == 0) ++ { ++ PUT_BITS_DP64(uy + 0x2590000000000000, y); ++ y -= 9.23297861778573578076e-128; /* 0x2590000000000000 */ ++ GET_BITS_DP64(y, uy); ++ } ++ else ++ { ++ uy += 0x2580000000000000; ++ PUT_BITS_DP64(uy, y); ++ } ++ } ++ ++ ++#ifdef FAST_BUT_GREATER_THAN_ONE_ULP ++ /* Not awful, but results in accuracy loss larger than 1 ulp */ ++ r = x*x + y*y ++#else ++ /* Slower but more accurate */ ++ ++ /* Sort so that x is greater than y */ ++ if (x < y) ++ { ++ u = y; ++ y = x; ++ x = u; ++ ut = ux; ++ ux = uy; ++ uy = ut; ++ } ++ ++ /* Split x into hx and tx, head and tail */ ++ PUT_BITS_DP64(ux & 0xfffffffff8000000, hx); ++ tx = x - hx; ++ ++ PUT_BITS_DP64(uy & 0xfffffffff8000000, hy); ++ ty = y - hy; ++ ++ /* Compute r = x*x + y*y with extra precision */ ++ x2 = x*x; ++ y2 = y*y; ++ hs = x2 + y2; ++ ++ if (dexp == 0) ++ /* We take most care when x and y have equal exponents, ++ i.e. are almost the same size */ ++ ts = (((x2 - hs) + y2) + ++ ((hx * hx - x2) + 2 * hx * tx) + tx * tx) + ++ ((hy * hy - y2) + 2 * hy * ty) + ty * ty; ++ else ++ ts = (((x2 - hs) + y2) + ++ ((hx * hx - x2) + 2 * hx * tx) + tx * tx); ++ ++ r = hs + ts; ++#endif ++ ++ /* The sqrt can introduce another half ulp error. */ ++ /* Hammer sqrt instruction */ ++ asm volatile ("sqrtsd %1, %0" : "=x" (retval) : "x" (r)); ++ ++ /* If necessary scale the result back. This may lead to ++ overflow but if so that's the correct result. */ ++ retval = scaleDouble_1(retval, expadjust); ++ ++ if (retval > large) ++ /* The result overflowed. Deal with errno. */ ++ return retval_errno_erange_overflow(x, y); ++ ++ return retval; ++} ++ ++weak_alias (__hypot, hypot) ++weak_alias (__hypot, __ieee754_hypot) +diff -urpN libc/sysdeps/x86_64/fpu/w_hypotf.c libc-amd/sysdeps/x86_64/fpu/w_hypotf.c +--- libc/sysdeps/x86_64/fpu/w_hypotf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_hypotf.c 2006-03-22 02:29:15.000000000 +0100 +@@ -0,0 +1,99 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#if USE_SOFTWARE_SQRT ++#define USE_SQRTF_AMD_INLINE ++#endif ++#define USE_INFINITYF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#if USE_SOFTWARE_SQRT ++#undef USE_SQRTF_AMD_INLINE ++#endif ++#undef USE_INFINITYF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange_overflow(float x, float y) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)y; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"hypotf"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = HUGE; ++ else ++ exc.retval = infinityf_with_flags(AMD_F_OVERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++float __hypotf(float x, float y) ++{ ++ /* Returns sqrt(x*x + y*y) with no overflow or underflow unless ++ the result warrants it */ ++ ++ /* Do intermediate computations in double precision ++ and use sqrt instruction from chip if available. */ ++ double dx = x, dy = y, dr, retval; ++ ++ /* The largest finite float, stored as a double */ ++ const double large = 3.40282346638528859812e+38; /* 0x47efffffe0000000 */ ++ ++ ++ unsigned long ux, uy, avx, avy; ++ ++ GET_BITS_DP64(x, avx); ++ avx &= ~SIGNBIT_DP64; ++ GET_BITS_DP64(y, avy); ++ avy &= ~SIGNBIT_DP64; ++ ux = (avx >> EXPSHIFTBITS_DP64); ++ uy = (avy >> EXPSHIFTBITS_DP64); ++ ++ if (ux == BIASEDEMAX_DP64 + 1 || uy == BIASEDEMAX_DP64 + 1) ++ { ++ retval = x*x + y*y; ++ /* One or both of the arguments are NaN or infinity. The ++ result will also be NaN or infinity. */ ++ if (((ux == BIASEDEMAX_DP64 + 1) && !(avx & MANTBITS_DP64)) || ++ ((uy == BIASEDEMAX_DP64 + 1) && !(avy & MANTBITS_DP64))) ++ /* x or y is infinity. ISO C99 defines that we must ++ return +infinity, even if the other argument is NaN. ++ Note that the computation of x*x + y*y above will already ++ have raised invalid if either x or y is a signalling NaN. */ ++ return infinityf_with_flags(0); ++ else ++ /* One or both of x or y is NaN, and neither is infinity. ++ Raise invalid if it's a signalling NaN */ ++ return retval; ++ } ++ ++ dr = (dx*dx + dy*dy); ++ ++#if USE_SOFTWARE_SQRT ++ retval = sqrtf_amd_inline(r); ++#else ++ /* Hammer sqrt instruction */ ++ asm volatile ("sqrtsd %1, %0" : "=x" (retval) : "x" (dr)); ++#endif ++ ++ if (retval > large) ++ return retval_errno_erange_overflow(x, y); ++ else ++ return retval; ++ } ++ ++weak_alias (__hypotf, hypotf) ++weak_alias (__hypotf, __ieee754_hypotf) +diff -urpN libc/sysdeps/x86_64/fpu/w_log10.c libc-amd/sysdeps/x86_64/fpu/w_log10.c +--- libc/sysdeps/x86_64/fpu/w_log10.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_log10.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,2 @@ ++#define COMPILING_LOG10 1 ++#include <w_log.c> +diff -urpN libc/sysdeps/x86_64/fpu/w_log10f.c libc-amd/sysdeps/x86_64/fpu/w_log10f.c +--- libc/sysdeps/x86_64/fpu/w_log10f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_log10f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,2 @@ ++#define COMPILING_LOG10 1 ++#include <w_logf.c> +diff -urpN libc/sysdeps/x86_64/fpu/w_log2.c libc-amd/sysdeps/x86_64/fpu/w_log2.c +--- libc/sysdeps/x86_64/fpu/w_log2.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_log2.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,2 @@ ++#define COMPILING_LOG2 1 ++#include <w_log.c> +diff -urpN libc/sysdeps/x86_64/fpu/w_log2f.c libc-amd/sysdeps/x86_64/fpu/w_log2f.c +--- libc/sysdeps/x86_64/fpu/w_log2f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_log2f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,2 @@ ++#define COMPILING_LOG2 1 ++#include <w_logf.c> +diff -urpN libc/sysdeps/x86_64/fpu/w_log.c libc-amd/sysdeps/x86_64/fpu/w_log.c +--- libc/sysdeps/x86_64/fpu/w_log.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_log.c 2006-03-22 02:29:34.000000000 +0100 +@@ -0,0 +1,490 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_NAN_WITH_FLAGS ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_INFINITY_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange_overflow(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = SING; ++#if defined(COMPILING_LOG10) ++ exc.name = (char *)"log10"; ++#elif defined(COMPILING_LOG2) ++ exc.name = (char *)"log2"; ++#else ++ exc.name = (char *)"log"; ++#endif ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = -HUGE; ++ else ++ exc.retval = -infinity_with_flags(AMD_F_DIVBYZERO); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++/* Deal with errno for out-of-range argument */ ++static inline double retval_errno_edom(double x) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = DOMAIN; ++#if defined(COMPILING_LOG10) ++ exc.name = (char *)"log10"; ++#elif defined(COMPILING_LOG2) ++ exc.name = (char *)"log2"; ++#else ++ exc.name = (char *)"log"; ++#endif ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = -HUGE; ++ else ++ exc.retval = nan_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++#if defined(COMPILING_LOG10) ++ (void)fputs("log10: DOMAIN error\n", stderr); ++#elif defined(COMPILING_LOG2) ++ (void)fputs("log2: DOMAIN error\n", stderr); ++#else ++ (void)fputs("log: DOMAIN error\n", stderr); ++#endif ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++#if defined(COMPILING_LOG10) ++double __log10(double x) ++#elif defined(COMPILING_LOG2) ++double __log2(double x) ++#else ++double __log(double x) ++#endif ++{ ++ ++ int expadjust, xexp; ++ double r, r1, r2, correction, f, f1, f2, q, u, v, z1, z2, poly; ++ int index; ++ unsigned long ux; ++#if defined(COMPILING_LOG10) || defined (COMPILING_LOG2) ++ unsigned long ut; ++#endif ++ ++ /* ++ Computes natural log(x). Algorithm based on: ++ Ping-Tak Peter Tang ++ "Table-driven implementation of the logarithm function in IEEE ++ floating-point arithmetic" ++ ACM Transactions on Mathematical Software (TOMS) ++ Volume 16, Issue 4 (December 1990) ++ */ ++ ++/* Arrays ln_lead_table and ln_tail_table contain ++ leading and trailing parts respectively of precomputed ++ values of natural log(1+i/64), for i = 0, 1, ..., 64. ++ ln_lead_table contains the first 24 bits of precision, ++ and ln_tail_table contains a further 53 bits precision. */ ++ ++ static const double ln_lead_table[65] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.55041813850402832031e-02, /* 0x3f8fc0a800000000 */ ++ 3.07716131210327148438e-02, /* 0x3f9f829800000000 */ ++ 4.58095073699951171875e-02, /* 0x3fa7745800000000 */ ++ 6.06245994567871093750e-02, /* 0x3faf0a3000000000 */ ++ 7.52233862876892089844e-02, /* 0x3fb341d700000000 */ ++ 8.96121263504028320312e-02, /* 0x3fb6f0d200000000 */ ++ 1.03796780109405517578e-01, /* 0x3fba926d00000000 */ ++ 1.17783010005950927734e-01, /* 0x3fbe270700000000 */ ++ 1.31576299667358398438e-01, /* 0x3fc0d77e00000000 */ ++ 1.45181953907012939453e-01, /* 0x3fc2955280000000 */ ++ 1.58604979515075683594e-01, /* 0x3fc44d2b00000000 */ ++ 1.71850204467773437500e-01, /* 0x3fc5ff3000000000 */ ++ 1.84922337532043457031e-01, /* 0x3fc7ab8900000000 */ ++ 1.97825729846954345703e-01, /* 0x3fc9525a80000000 */ ++ 2.10564732551574707031e-01, /* 0x3fcaf3c900000000 */ ++ 2.23143517971038818359e-01, /* 0x3fcc8ff780000000 */ ++ 2.35566020011901855469e-01, /* 0x3fce270700000000 */ ++ 2.47836112976074218750e-01, /* 0x3fcfb91800000000 */ ++ 2.59957492351531982422e-01, /* 0x3fd0a324c0000000 */ ++ 2.71933674812316894531e-01, /* 0x3fd1675c80000000 */ ++ 2.83768117427825927734e-01, /* 0x3fd22941c0000000 */ ++ 2.95464158058166503906e-01, /* 0x3fd2e8e280000000 */ ++ 3.07025015354156494141e-01, /* 0x3fd3a64c40000000 */ ++ 3.18453729152679443359e-01, /* 0x3fd4618bc0000000 */ ++ 3.29753279685974121094e-01, /* 0x3fd51aad80000000 */ ++ 3.40926527976989746094e-01, /* 0x3fd5d1bd80000000 */ ++ 3.51976394653320312500e-01, /* 0x3fd686c800000000 */ ++ 3.62905442714691162109e-01, /* 0x3fd739d7c0000000 */ ++ 3.73716354370117187500e-01, /* 0x3fd7eaf800000000 */ ++ 3.84411692619323730469e-01, /* 0x3fd89a3380000000 */ ++ 3.94993782043457031250e-01, /* 0x3fd9479400000000 */ ++ 4.05465066432952880859e-01, /* 0x3fd9f323c0000000 */ ++ 4.15827870368957519531e-01, /* 0x3fda9cec80000000 */ ++ 4.26084339618682861328e-01, /* 0x3fdb44f740000000 */ ++ 4.36236739158630371094e-01, /* 0x3fdbeb4d80000000 */ ++ 4.46287095546722412109e-01, /* 0x3fdc8ff7c0000000 */ ++ 4.56237375736236572266e-01, /* 0x3fdd32fe40000000 */ ++ 4.66089725494384765625e-01, /* 0x3fddd46a00000000 */ ++ 4.75845873355865478516e-01, /* 0x3fde744240000000 */ ++ 4.85507786273956298828e-01, /* 0x3fdf128f40000000 */ ++ 4.95077252388000488281e-01, /* 0x3fdfaf5880000000 */ ++ 5.04556000232696533203e-01, /* 0x3fe02552a0000000 */ ++ 5.13945698738098144531e-01, /* 0x3fe0723e40000000 */ ++ 5.23248136043548583984e-01, /* 0x3fe0be72e0000000 */ ++ 5.32464742660522460938e-01, /* 0x3fe109f380000000 */ ++ 5.41597247123718261719e-01, /* 0x3fe154c3c0000000 */ ++ 5.50647079944610595703e-01, /* 0x3fe19ee6a0000000 */ ++ 5.59615731239318847656e-01, /* 0x3fe1e85f40000000 */ ++ 5.68504691123962402344e-01, /* 0x3fe23130c0000000 */ ++ 5.77315330505371093750e-01, /* 0x3fe2795e00000000 */ ++ 5.86049020290374755859e-01, /* 0x3fe2c0e9e0000000 */ ++ 5.94707071781158447266e-01, /* 0x3fe307d720000000 */ ++ 6.03290796279907226562e-01, /* 0x3fe34e2880000000 */ ++ 6.11801505088806152344e-01, /* 0x3fe393e0c0000000 */ ++ 6.20240390300750732422e-01, /* 0x3fe3d90260000000 */ ++ 6.28608644008636474609e-01, /* 0x3fe41d8fe0000000 */ ++ 6.36907458305358886719e-01, /* 0x3fe4618bc0000000 */ ++ 6.45137906074523925781e-01, /* 0x3fe4a4f840000000 */ ++ 6.53301239013671875000e-01, /* 0x3fe4e7d800000000 */ ++ 6.61398470401763916016e-01, /* 0x3fe52a2d20000000 */ ++ 6.69430613517761230469e-01, /* 0x3fe56bf9c0000000 */ ++ 6.77398800849914550781e-01, /* 0x3fe5ad4040000000 */ ++ 6.85303986072540283203e-01, /* 0x3fe5ee02a0000000 */ ++ 6.93147122859954833984e-01}; /* 0x3fe62e42e0000000 */ ++ ++ static const double ln_tail_table[65] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 5.15092497094772879206e-09, /* 0x3e361f807c79f3db */ ++ 4.55457209735272790188e-08, /* 0x3e6873c1980267c8 */ ++ 2.86612990859791781788e-08, /* 0x3e5ec65b9f88c69e */ ++ 2.23596477332056055352e-08, /* 0x3e58022c54cc2f99 */ ++ 3.49498983167142274770e-08, /* 0x3e62c37a3a125330 */ ++ 3.23392843005887000414e-08, /* 0x3e615cad69737c93 */ ++ 1.35722380472479366661e-08, /* 0x3e4d256ab1b285e9 */ ++ 2.56504325268044191098e-08, /* 0x3e5b8abcb97a7aa2 */ ++ 5.81213608741512136843e-08, /* 0x3e6f34239659a5dc */ ++ 5.59374849578288093334e-08, /* 0x3e6e07fd48d30177 */ ++ 5.06615629004996189970e-08, /* 0x3e6b32df4799f4f6 */ ++ 5.24588857848400955725e-08, /* 0x3e6c29e4f4f21cf8 */ ++ 9.61968535632653505972e-10, /* 0x3e1086c848df1b59 */ ++ 1.34829655346594463137e-08, /* 0x3e4cf456b4764130 */ ++ 3.65557749306383026498e-08, /* 0x3e63a02ffcb63398 */ ++ 3.33431709374069198903e-08, /* 0x3e61e6a6886b0976 */ ++ 5.13008650536088382197e-08, /* 0x3e6b8abcb97a7aa2 */ ++ 5.09285070380306053751e-08, /* 0x3e6b578f8aa35552 */ ++ 3.20853940845502057341e-08, /* 0x3e6139c871afb9fc */ ++ 4.06713248643004200446e-08, /* 0x3e65d5d30701ce64 */ ++ 5.57028186706125221168e-08, /* 0x3e6de7bcb2d12142 */ ++ 5.48356693724804282546e-08, /* 0x3e6d708e984e1664 */ ++ 1.99407553679345001938e-08, /* 0x3e556945e9c72f36 */ ++ 1.96585517245087232086e-09, /* 0x3e20e2f613e85bda */ ++ 6.68649386072067321503e-09, /* 0x3e3cb7e0b42724f6 */ ++ 5.89936034642113390002e-08, /* 0x3e6fac04e52846c7 */ ++ 2.85038578721554472484e-08, /* 0x3e5e9b14aec442be */ ++ 5.09746772910284482606e-08, /* 0x3e6b5de8034e7126 */ ++ 5.54234668933210171467e-08, /* 0x3e6dc157e1b259d3 */ ++ 6.29100830926604004874e-09, /* 0x3e3b05096ad69c62 */ ++ 2.61974119468563937716e-08, /* 0x3e5c2116faba4cdd */ ++ 4.16752115011186398935e-08, /* 0x3e665fcc25f95b47 */ ++ 2.47747534460820790327e-08, /* 0x3e5a9a08498d4850 */ ++ 5.56922172017964209793e-08, /* 0x3e6de647b1465f77 */ ++ 2.76162876992552906035e-08, /* 0x3e5da71b7bf7861d */ ++ 7.08169709942321478061e-09, /* 0x3e3e6a6886b09760 */ ++ 5.77453510221151779025e-08, /* 0x3e6f0075eab0ef64 */ ++ 4.43021445893361960146e-09, /* 0x3e33071282fb989b */ ++ 3.15140984357495864573e-08, /* 0x3e60eb43c3f1bed2 */ ++ 2.95077445089736670973e-08, /* 0x3e5faf06ecb35c84 */ ++ 1.44098510263167149349e-08, /* 0x3e4ef1e63db35f68 */ ++ 1.05196987538551827693e-08, /* 0x3e469743fb1a71a5 */ ++ 5.23641361722697546261e-08, /* 0x3e6c1cdf404e5796 */ ++ 7.72099925253243069458e-09, /* 0x3e4094aa0ada625e */ ++ 5.62089493829364197156e-08, /* 0x3e6e2d4c96fde3ec */ ++ 3.53090261098577946927e-08, /* 0x3e62f4d5e9a98f34 */ ++ 3.80080516835568242269e-08, /* 0x3e6467c96ecc5cbe */ ++ 5.66961038386146408282e-08, /* 0x3e6e7040d03dec5a */ ++ 4.42287063097349852717e-08, /* 0x3e67bebf4282de36 */ ++ 3.45294525105681104660e-08, /* 0x3e6289b11aeb783f */ ++ 2.47132034530447431509e-08, /* 0x3e5a891d1772f538 */ ++ 3.59655343422487209774e-08, /* 0x3e634f10be1fb591 */ ++ 5.51581770357780862071e-08, /* 0x3e6d9ce1d316eb93 */ ++ 3.60171867511861372793e-08, /* 0x3e63562a19a9c442 */ ++ 1.94511067964296180547e-08, /* 0x3e54e2adf548084c */ ++ 1.54137376631349347838e-08, /* 0x3e508ce55cc8c97a */ ++ 3.93171034490174464173e-09, /* 0x3e30e2f613e85bda */ ++ 5.52990607758839766440e-08, /* 0x3e6db03ebb0227bf */ ++ 3.29990737637586136511e-08, /* 0x3e61b75bb09cb098 */ ++ 1.18436010922446096216e-08, /* 0x3e496f16abb9df22 */ ++ 4.04248680368301346709e-08, /* 0x3e65b3f399411c62 */ ++ 2.27418915900284316293e-08, /* 0x3e586b3e59f65355 */ ++ 1.70263791333409206020e-08, /* 0x3e52482ceae1ac12 */ ++ 5.76999904754328540596e-08}; /* 0x3e6efa39ef35793c */ ++ ++#ifndef COMPILING_LOG2 ++ /* log2_lead and log2_tail sum to an extra-precise version ++ of log(2) */ ++ static const double ++ log2_lead = 6.93147122859954833984e-01, /* 0x3fe62e42e0000000 */ ++ log2_tail = 5.76999904754328540596e-08; /* 0x3e6efa39ef35793c */ ++#endif ++ ++ static const double ++ /* Approximating polynomial coefficients for x near 1.0 */ ++ ca_1 = 8.33333333333317923934e-02, /* 0x3fb55555555554e6 */ ++ ca_2 = 1.25000000037717509602e-02, /* 0x3f89999999bac6d4 */ ++ ca_3 = 2.23213998791944806202e-03, /* 0x3f62492307f1519f */ ++ ca_4 = 4.34887777707614552256e-04, /* 0x3f3c8034c85dfff0 */ ++ ++ /* Approximating polynomial coefficients for other x */ ++ cb_1 = 8.33333333333333593622e-02, /* 0x3fb5555555555557 */ ++ cb_2 = 1.24999999978138668903e-02, /* 0x3f89999999865ede */ ++ cb_3 = 2.23219810758559851206e-03; /* 0x3f6249423bd94741 */ ++ ++#if defined(COMPILING_LOG10) ++ /* log10e_lead and log10e_tail sum to an extra-precision ++ version of log10(e) (19 bits in lead) */ ++ static const double ++ log10e_lead = 4.34293746948242187500e-01, /* 0x3fdbcb7800000000 */ ++ log10e_tail = 7.3495500964015109100644e-7; /* 0x3ea8a93728719535 */ ++#elif defined(COMPILING_LOG2) ++ /* log2e_lead and log2e_tail sum to an extra-precision ++ version of log2(e) (19 bits in lead) */ ++ static const double ++ log2e_lead = 1.44269180297851562500E+00, /* 0x3FF7154400000000 */ ++ log2e_tail = 3.23791044778235969970E-06; /* 0x3ECB295C17F0BBBE */ ++#endif ++ ++ static const unsigned long ++ log_thresh1 = 0x3fee0faa00000000, ++ log_thresh2 = 0x3ff1082c00000000; ++ ++ ++ GET_BITS_DP64(x, ux); ++ ++ if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return x + x; /* Raise invalid if it is a signalling NaN */ ++ else ++ { ++ /* x is infinity */ ++ if (ux & SIGNBIT_DP64) ++ /* x is negative infinity. Return a NaN. */ ++ return retval_errno_edom(x); ++ else ++ return x; ++ } ++ } ++ else if (!(ux & ~SIGNBIT_DP64)) ++ /* x is +/-zero. Return -infinity with div-by-zero flag. */ ++ return retval_errno_erange_overflow(x); ++ else if (ux & SIGNBIT_DP64) ++ /* x is negative. Return a NaN. */ ++ return retval_errno_edom(x); ++ ++ ++ /* log_thresh1 = 9.39412117004394531250e-1 = 0x3fee0faa00000000 ++ log_thresh2 = 1.06449508666992187500 = 0x3ff1082c00000000 */ ++ if (ux >= log_thresh1 && ux <= log_thresh2) ++ { ++ /* Arguments close to 1.0 are handled separately to maintain ++ accuracy. ++ ++ The approximation in this region exploits the identity ++ log( 1 + r ) = log( 1 + u/2 ) - log( 1 - u/2 ), where ++ u = 2r / (2+r). ++ Note that the right hand side has an odd Taylor series expansion ++ which converges much faster than the Taylor series expansion of ++ log( 1 + r ) in r. Thus, we approximate log( 1 + r ) by ++ u + A1 * u^3 + A2 * u^5 + ... + An * u^(2n+1). ++ ++ One subtlety is that since u cannot be calculated from ++ r exactly, the rounding error in the first u should be ++ avoided if possible. To accomplish this, we observe that ++ u = r - r*r/(2+r). ++ Since x (=1+r) is the input argument, and thus presumed exact, ++ the formula above approximates u accurately because ++ u = r - correction, ++ and the magnitude of "correction" (of the order of r*r) ++ is small. ++ With these observations, we will approximate log( 1 + r ) by ++ r + ( (A1*u^3 + ... + An*u^(2n+1)) - correction ). ++ ++ We approximate log(1+r) by an odd polynomial in u, where ++ u = 2r/(2+r) = r - r*r/(2+r). ++ */ ++ r = x - 1.0; ++ u = r / (2.0 + r); ++ correction = r * u; ++ u = u + u; ++ v = u * u; ++ r1 = r; ++ r2 = (u * v * (ca_1 + v * (ca_2 + v * (ca_3 + v * ca_4))) - correction); ++#if defined(COMPILING_LOG10) ++ /* At this point r1,r2 is an extra-precise approximation to ++ natural log(x). Convert it to log10(x) by multiplying ++ carefully by log10(e). ++ Shift some bits from r1 to r2 so that log10e_lead*r1 ++ can be computed without rounding error */ ++ r = r1; ++ GET_BITS_DP64(r1, ut); ++ PUT_BITS_DP64(ut & 0xffffffff00000000, r1); ++ r2 = r2 + (r - r1); ++ return (((log10e_tail*r2) + log10e_tail*r1) + log10e_lead*r2) + ++ log10e_lead*r1; ++#elif defined(COMPILING_LOG2) ++ /* Similarly handle log2(x) by multiplying carefully by log2(e). */ ++ r = r1; ++ GET_BITS_DP64(r1, ut); ++ PUT_BITS_DP64(ut & 0xffffffff00000000, r1); ++ r2 = r2 + (r - r1); ++ return (((log2e_tail*r2) + log2e_tail*r1) + log2e_lead*r2) + ++ log2e_lead*r1; ++#else ++ return r1 + r2; ++#endif ++ } ++ else ++ { ++ /* ++ First, we decompose the argument x to the form ++ x = 2**M * (F1 + F2), ++ where 1 <= F1+F2 < 2, M has the value of an integer, ++ F1 = 1 + j/64, j ranges from 0 to 64, and |F2| <= 1/128. ++ ++ Second, we approximate log( 1 + F2/F1 ) by an odd polynomial ++ in U, where U = 2 F2 / (2 F1 + F2). ++ Note that log( 1 + F2/F1 ) = log( 1 + U/2 ) - log( 1 - U/2 ). ++ The core approximation calculates ++ Poly = [log( 1 + U/2 ) - log( 1 - U/2 )]/U - 1. ++ Note that log(1 + U/2) - log(1 - U/2) = 2 arctanh ( U/2 ), ++ thus, Poly = 2 arctanh( U/2 ) / U - 1. ++ ++ It is not hard to see that ++ log(x) = M*log(2) + log(F1) + log( 1 + F2/F1 ). ++ Hence, we return Z1 = log(F1), and Z2 = log( 1 + F2/F1). ++ The values of log(F1) are calculated beforehand and stored ++ in the program. ++ */ ++ ++ if (ux < IMPBIT_DP64) ++ { ++ /* The input argument x is denormalized */ ++ /* Normalize f by increasing the exponent by 60 ++ and subtracting a correction to account for the implicit ++ bit. This replaces a slow denormalized ++ multiplication by a fast normal subtraction. */ ++ static const double corr = 2.5653355008114851558350183e-290; /* 0x03d0000000000000 */ ++ PUT_BITS_DP64(ux | 0x03d0000000000000, f); ++ f -= corr; ++ GET_BITS_DP64(f, ux); ++ expadjust = 60; ++ } ++ else ++ { ++ f = x; ++ expadjust = 0; ++ } ++ ++ /* Store the exponent of x in xexp and put ++ f into the range [0.5,1) */ ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64 - expadjust; ++ PUT_BITS_DP64((ux & MANTBITS_DP64) | HALFEXPBITS_DP64, f); ++ ++ /* Now x = 2**xexp * f, 1/2 <= f < 1. */ ++ ++ /* Set index to be the nearest integer to 128*f */ ++ /* ++ r = 128.0 * f; ++ index = (int)(r + 0.5); ++ */ ++ /* This code instead of the above can save several cycles. ++ It only works because 64 <= r < 128, so ++ the nearest integer is always contained in exactly ++ 7 bits, and the right shift is always the same. */ ++ index = (((ux & 0x000fc00000000000) | 0x0010000000000000) >> 46) ++ + ((ux & 0x0000200000000000) >> 45); ++ ++ z1 = ln_lead_table[index-64]; ++ q = ln_tail_table[index-64]; ++ f1 = index * 0.0078125; /* 0.0078125 = 1/128 */ ++ f2 = f - f1; ++ /* At this point, x = 2**xexp * ( f1 + f2 ) where ++ f1 = j/128, j = 64, 65, ..., 128 and |f2| <= 1/256. */ ++ ++ /* Calculate u = 2 f2 / ( 2 f1 + f2 ) = f2 / ( f1 + 0.5*f2 ) */ ++ u = f2 / (f1 + 0.5 * f2); ++ ++ /* Here, |u| <= 2(exp(1/16)-1) / (exp(1/16)+1). ++ The core approximation calculates ++ poly = [log(1 + u/2) - log(1 - u/2)]/u - 1 */ ++ v = u * u; ++ poly = (v * (cb_1 + v * (cb_2 + v * cb_3))); ++ z2 = q + (u + u * poly); ++ ++ /* Now z1,z2 is an extra-precise approximation of log(2f). */ ++ ++#if defined (COMPILING_LOG10) ++ /* Add xexp * log(2) to z1,z2 to get log(x). */ ++ r1 = (xexp * log2_lead + z1); ++ r2 = (xexp * log2_tail + z2); ++ /* At this point r1,r2 is an extra-precise approximation to ++ natural log(x). Convert it to log10(x) by multiplying ++ carefully by log10(e). */ ++ return (((log10e_tail*r2) + log10e_tail*r1) + log10e_lead*r2) + ++ log10e_lead*r1; ++#elif defined(COMPILING_LOG2) ++ /* Convert to log2(x) by multiplying carefully by log2(e) ++ and adding xexp. */ ++ r1 = xexp + log2e_lead*z1; ++ r2 = (((log2e_tail*z2) + log2e_tail*z1) + log2e_lead*z2); ++ return r1 + r2; ++#else ++ /* Add xexp * log(2) to z1,z2 to get the result log(x). ++ The computed r1 is not subject to rounding error because ++ xexp has at most 10 significant bits, log(2) has 24 significant ++ bits, and z1 has up to 24 bits; and the exponents of z1 ++ and z2 differ by at most 6. */ ++ r1 = (xexp * log2_lead + z1); ++ r2 = (xexp * log2_tail + z2); ++ /* Natural log(x) */ ++ return r1 + r2; ++#endif ++ } ++} ++ ++#if defined(COMPILING_LOG10) ++weak_alias (__log10, log10) ++weak_alias (__log10, __ieee754_log10) ++#elif defined(COMPILING_LOG2) ++weak_alias (__log2, log2) ++weak_alias (__log2, __ieee754_log2) ++#else ++weak_alias (__log, log) ++weak_alias (__log, __ieee754_log) ++#endif +diff -urpN libc/sysdeps/x86_64/fpu/w_logf.c libc-amd/sysdeps/x86_64/fpu/w_logf.c +--- libc/sysdeps/x86_64/fpu/w_logf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_logf.c 2006-03-22 02:29:52.000000000 +0100 +@@ -0,0 +1,376 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_NANF_WITH_FLAGS ++#define USE_INFINITYF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_NANF_WITH_FLAGS ++#undef USE_INFINITYF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange_overflow(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = SING; ++#if defined(COMPILING_LOG10) ++ exc.name = (char *)"log10f"; ++#elif defined(COMPILING_LOG2) ++ exc.name = (char *)"log2f"; ++#else ++ exc.name = (char *)"logf"; ++#endif ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = -HUGE; ++ else ++ exc.retval = -infinityf_with_flags(AMD_F_DIVBYZERO); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++/* Deal with errno for out-of-range argument */ ++static inline float retval_errno_edom(float x) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = DOMAIN; ++#if defined(COMPILING_LOG10) ++ exc.name = (char *)"log10f"; ++#elif defined(COMPILING_LOG2) ++ exc.name = (char *)"log2f"; ++#else ++ exc.name = (char *)"logf"; ++#endif ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = -HUGE; ++ else ++ exc.retval = nanf_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(EDOM); ++ else if (!matherr(&exc)) ++ { ++ if(_LIB_VERSION == _SVID_) ++#if defined(COMPILING_LOG10) ++ (void)fputs("log10f: DOMAIN error\n", stderr); ++#elif defined(COMPILING_LOG2) ++ (void)fputs("log2f: DOMAIN error\n", stderr); ++#else ++ (void)fputs("logf: DOMAIN error\n", stderr); ++#endif ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++#if defined(COMPILING_LOG10) ++float __log10f(float fx) ++#elif defined(COMPILING_LOG2) ++float __log2f(float fx) ++#else ++float __logf(float fx) ++#endif ++{ ++ ++ double x = fx; ++ ++ int xexp; ++ double r, f, f1, f2, q, u, v, z1, z2, poly; ++ int index; ++ unsigned long ux; ++ ++ /* ++ Computes natural log(x) for float arguments. Algorithm is ++ basically a promotion of the arguments to double followed ++ by an inlined version of the double algorithm, simplified ++ for efficiency (see log_amd.c). Simplifications include: ++ * Special algorithm for arguments near 1.0 not required ++ * Scaling of denormalised arguments not required ++ * Shorter core series approximations used ++ */ ++ ++/* Arrays ln_lead_table and ln_tail_table contain ++ leading and trailing parts respectively of precomputed ++ values of natural log(1+i/64), for i = 0, 1, ..., 64. ++ ln_lead_table contains the first 24 bits of precision, ++ and ln_tail_table contains a further 53 bits precision. */ ++ ++ static const double ln_lead_table[65] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.55041813850402832031e-02, /* 0x3f8fc0a800000000 */ ++ 3.07716131210327148438e-02, /* 0x3f9f829800000000 */ ++ 4.58095073699951171875e-02, /* 0x3fa7745800000000 */ ++ 6.06245994567871093750e-02, /* 0x3faf0a3000000000 */ ++ 7.52233862876892089844e-02, /* 0x3fb341d700000000 */ ++ 8.96121263504028320312e-02, /* 0x3fb6f0d200000000 */ ++ 1.03796780109405517578e-01, /* 0x3fba926d00000000 */ ++ 1.17783010005950927734e-01, /* 0x3fbe270700000000 */ ++ 1.31576299667358398438e-01, /* 0x3fc0d77e00000000 */ ++ 1.45181953907012939453e-01, /* 0x3fc2955280000000 */ ++ 1.58604979515075683594e-01, /* 0x3fc44d2b00000000 */ ++ 1.71850204467773437500e-01, /* 0x3fc5ff3000000000 */ ++ 1.84922337532043457031e-01, /* 0x3fc7ab8900000000 */ ++ 1.97825729846954345703e-01, /* 0x3fc9525a80000000 */ ++ 2.10564732551574707031e-01, /* 0x3fcaf3c900000000 */ ++ 2.23143517971038818359e-01, /* 0x3fcc8ff780000000 */ ++ 2.35566020011901855469e-01, /* 0x3fce270700000000 */ ++ 2.47836112976074218750e-01, /* 0x3fcfb91800000000 */ ++ 2.59957492351531982422e-01, /* 0x3fd0a324c0000000 */ ++ 2.71933674812316894531e-01, /* 0x3fd1675c80000000 */ ++ 2.83768117427825927734e-01, /* 0x3fd22941c0000000 */ ++ 2.95464158058166503906e-01, /* 0x3fd2e8e280000000 */ ++ 3.07025015354156494141e-01, /* 0x3fd3a64c40000000 */ ++ 3.18453729152679443359e-01, /* 0x3fd4618bc0000000 */ ++ 3.29753279685974121094e-01, /* 0x3fd51aad80000000 */ ++ 3.40926527976989746094e-01, /* 0x3fd5d1bd80000000 */ ++ 3.51976394653320312500e-01, /* 0x3fd686c800000000 */ ++ 3.62905442714691162109e-01, /* 0x3fd739d7c0000000 */ ++ 3.73716354370117187500e-01, /* 0x3fd7eaf800000000 */ ++ 3.84411692619323730469e-01, /* 0x3fd89a3380000000 */ ++ 3.94993782043457031250e-01, /* 0x3fd9479400000000 */ ++ 4.05465066432952880859e-01, /* 0x3fd9f323c0000000 */ ++ 4.15827870368957519531e-01, /* 0x3fda9cec80000000 */ ++ 4.26084339618682861328e-01, /* 0x3fdb44f740000000 */ ++ 4.36236739158630371094e-01, /* 0x3fdbeb4d80000000 */ ++ 4.46287095546722412109e-01, /* 0x3fdc8ff7c0000000 */ ++ 4.56237375736236572266e-01, /* 0x3fdd32fe40000000 */ ++ 4.66089725494384765625e-01, /* 0x3fddd46a00000000 */ ++ 4.75845873355865478516e-01, /* 0x3fde744240000000 */ ++ 4.85507786273956298828e-01, /* 0x3fdf128f40000000 */ ++ 4.95077252388000488281e-01, /* 0x3fdfaf5880000000 */ ++ 5.04556000232696533203e-01, /* 0x3fe02552a0000000 */ ++ 5.13945698738098144531e-01, /* 0x3fe0723e40000000 */ ++ 5.23248136043548583984e-01, /* 0x3fe0be72e0000000 */ ++ 5.32464742660522460938e-01, /* 0x3fe109f380000000 */ ++ 5.41597247123718261719e-01, /* 0x3fe154c3c0000000 */ ++ 5.50647079944610595703e-01, /* 0x3fe19ee6a0000000 */ ++ 5.59615731239318847656e-01, /* 0x3fe1e85f40000000 */ ++ 5.68504691123962402344e-01, /* 0x3fe23130c0000000 */ ++ 5.77315330505371093750e-01, /* 0x3fe2795e00000000 */ ++ 5.86049020290374755859e-01, /* 0x3fe2c0e9e0000000 */ ++ 5.94707071781158447266e-01, /* 0x3fe307d720000000 */ ++ 6.03290796279907226562e-01, /* 0x3fe34e2880000000 */ ++ 6.11801505088806152344e-01, /* 0x3fe393e0c0000000 */ ++ 6.20240390300750732422e-01, /* 0x3fe3d90260000000 */ ++ 6.28608644008636474609e-01, /* 0x3fe41d8fe0000000 */ ++ 6.36907458305358886719e-01, /* 0x3fe4618bc0000000 */ ++ 6.45137906074523925781e-01, /* 0x3fe4a4f840000000 */ ++ 6.53301239013671875000e-01, /* 0x3fe4e7d800000000 */ ++ 6.61398470401763916016e-01, /* 0x3fe52a2d20000000 */ ++ 6.69430613517761230469e-01, /* 0x3fe56bf9c0000000 */ ++ 6.77398800849914550781e-01, /* 0x3fe5ad4040000000 */ ++ 6.85303986072540283203e-01, /* 0x3fe5ee02a0000000 */ ++ 6.93147122859954833984e-01}; /* 0x3fe62e42e0000000 */ ++ ++ static const double ln_tail_table[65] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 5.15092497094772879206e-09, /* 0x3e361f807c79f3db */ ++ 4.55457209735272790188e-08, /* 0x3e6873c1980267c8 */ ++ 2.86612990859791781788e-08, /* 0x3e5ec65b9f88c69e */ ++ 2.23596477332056055352e-08, /* 0x3e58022c54cc2f99 */ ++ 3.49498983167142274770e-08, /* 0x3e62c37a3a125330 */ ++ 3.23392843005887000414e-08, /* 0x3e615cad69737c93 */ ++ 1.35722380472479366661e-08, /* 0x3e4d256ab1b285e9 */ ++ 2.56504325268044191098e-08, /* 0x3e5b8abcb97a7aa2 */ ++ 5.81213608741512136843e-08, /* 0x3e6f34239659a5dc */ ++ 5.59374849578288093334e-08, /* 0x3e6e07fd48d30177 */ ++ 5.06615629004996189970e-08, /* 0x3e6b32df4799f4f6 */ ++ 5.24588857848400955725e-08, /* 0x3e6c29e4f4f21cf8 */ ++ 9.61968535632653505972e-10, /* 0x3e1086c848df1b59 */ ++ 1.34829655346594463137e-08, /* 0x3e4cf456b4764130 */ ++ 3.65557749306383026498e-08, /* 0x3e63a02ffcb63398 */ ++ 3.33431709374069198903e-08, /* 0x3e61e6a6886b0976 */ ++ 5.13008650536088382197e-08, /* 0x3e6b8abcb97a7aa2 */ ++ 5.09285070380306053751e-08, /* 0x3e6b578f8aa35552 */ ++ 3.20853940845502057341e-08, /* 0x3e6139c871afb9fc */ ++ 4.06713248643004200446e-08, /* 0x3e65d5d30701ce64 */ ++ 5.57028186706125221168e-08, /* 0x3e6de7bcb2d12142 */ ++ 5.48356693724804282546e-08, /* 0x3e6d708e984e1664 */ ++ 1.99407553679345001938e-08, /* 0x3e556945e9c72f36 */ ++ 1.96585517245087232086e-09, /* 0x3e20e2f613e85bda */ ++ 6.68649386072067321503e-09, /* 0x3e3cb7e0b42724f6 */ ++ 5.89936034642113390002e-08, /* 0x3e6fac04e52846c7 */ ++ 2.85038578721554472484e-08, /* 0x3e5e9b14aec442be */ ++ 5.09746772910284482606e-08, /* 0x3e6b5de8034e7126 */ ++ 5.54234668933210171467e-08, /* 0x3e6dc157e1b259d3 */ ++ 6.29100830926604004874e-09, /* 0x3e3b05096ad69c62 */ ++ 2.61974119468563937716e-08, /* 0x3e5c2116faba4cdd */ ++ 4.16752115011186398935e-08, /* 0x3e665fcc25f95b47 */ ++ 2.47747534460820790327e-08, /* 0x3e5a9a08498d4850 */ ++ 5.56922172017964209793e-08, /* 0x3e6de647b1465f77 */ ++ 2.76162876992552906035e-08, /* 0x3e5da71b7bf7861d */ ++ 7.08169709942321478061e-09, /* 0x3e3e6a6886b09760 */ ++ 5.77453510221151779025e-08, /* 0x3e6f0075eab0ef64 */ ++ 4.43021445893361960146e-09, /* 0x3e33071282fb989b */ ++ 3.15140984357495864573e-08, /* 0x3e60eb43c3f1bed2 */ ++ 2.95077445089736670973e-08, /* 0x3e5faf06ecb35c84 */ ++ 1.44098510263167149349e-08, /* 0x3e4ef1e63db35f68 */ ++ 1.05196987538551827693e-08, /* 0x3e469743fb1a71a5 */ ++ 5.23641361722697546261e-08, /* 0x3e6c1cdf404e5796 */ ++ 7.72099925253243069458e-09, /* 0x3e4094aa0ada625e */ ++ 5.62089493829364197156e-08, /* 0x3e6e2d4c96fde3ec */ ++ 3.53090261098577946927e-08, /* 0x3e62f4d5e9a98f34 */ ++ 3.80080516835568242269e-08, /* 0x3e6467c96ecc5cbe */ ++ 5.66961038386146408282e-08, /* 0x3e6e7040d03dec5a */ ++ 4.42287063097349852717e-08, /* 0x3e67bebf4282de36 */ ++ 3.45294525105681104660e-08, /* 0x3e6289b11aeb783f */ ++ 2.47132034530447431509e-08, /* 0x3e5a891d1772f538 */ ++ 3.59655343422487209774e-08, /* 0x3e634f10be1fb591 */ ++ 5.51581770357780862071e-08, /* 0x3e6d9ce1d316eb93 */ ++ 3.60171867511861372793e-08, /* 0x3e63562a19a9c442 */ ++ 1.94511067964296180547e-08, /* 0x3e54e2adf548084c */ ++ 1.54137376631349347838e-08, /* 0x3e508ce55cc8c97a */ ++ 3.93171034490174464173e-09, /* 0x3e30e2f613e85bda */ ++ 5.52990607758839766440e-08, /* 0x3e6db03ebb0227bf */ ++ 3.29990737637586136511e-08, /* 0x3e61b75bb09cb098 */ ++ 1.18436010922446096216e-08, /* 0x3e496f16abb9df22 */ ++ 4.04248680368301346709e-08, /* 0x3e65b3f399411c62 */ ++ 2.27418915900284316293e-08, /* 0x3e586b3e59f65355 */ ++ 1.70263791333409206020e-08, /* 0x3e52482ceae1ac12 */ ++ 5.76999904754328540596e-08}; /* 0x3e6efa39ef35793c */ ++ ++ static const double ++ log2 = 6.931471805599453e-01, /* 0x3fe62e42fefa39ef */ ++ ++ /* Approximating polynomial coefficients */ ++ cb_1 = 8.33333333333333593622e-02, /* 0x3fb5555555555557 */ ++ cb_2 = 1.24999999978138668903e-02; /* 0x3f89999999865ede */ ++ ++#if defined(COMPILING_LOG10) ++ static const double ++ log10e = 4.34294481903251827651e-01; /* 0x3fdbcb7b1526e50e */ ++#elif defined(COMPILING_LOG2) ++ static const double ++ log2e = 1.44269504088896340735e+00; /* 0x3ff71547652b82fe */ ++#endif ++ ++ ++ GET_BITS_DP64(x, ux); ++ ++#if !defined(COMPILING_LOG10) && !defined(COMPILING_LOG2) ++ if (ux == 0x4005bf0a80000000) ++ /* Treat this, the number closest to e in float arithmetic, ++ as a special case and return 1.0 */ ++ return 1.0F; ++#endif ++ ++ if ((ux & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is either NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return fx + fx; /* Raise invalid if it is a signalling NaN */ ++ else ++ { ++ /* x is infinity */ ++ if (ux & SIGNBIT_DP64) ++ /* x is negative infinity. Return a NaN. */ ++ return retval_errno_edom(fx); ++ else ++ return fx; ++ } ++ } ++ else if (!(ux & ~SIGNBIT_DP64)) ++ /* x is +/-zero. Return -infinity with div-by-zero flag. */ ++ return retval_errno_erange_overflow(fx); ++ else if (ux & SIGNBIT_DP64) ++ /* x is negative. Return a NaN. */ ++ return retval_errno_edom(fx); ++ ++ ++ /* ++ First, we decompose the argument x to the form ++ x = 2**M * (F1 + F2), ++ where 1 <= F1+F2 < 2, M has the value of an integer, ++ F1 = 1 + j/64, j ranges from 0 to 64, and |F2| <= 1/128. ++ ++ Second, we approximate log( 1 + F2/F1 ) by an odd polynomial ++ in U, where U = 2 F2 / (2 F2 + F1). ++ Note that log( 1 + F2/F1 ) = log( 1 + U/2 ) - log( 1 - U/2 ). ++ The core approximation calculates ++ Poly = [log( 1 + U/2 ) - log( 1 - U/2 )]/U - 1. ++ Note that log(1 + U/2) - log(1 - U/2) = 2 arctanh ( U/2 ), ++ thus, Poly = 2 arctanh( U/2 ) / U - 1. ++ ++ It is not hard to see that ++ log(x) = M*log(2) + log(F1) + log( 1 + F2/F1 ). ++ Hence, we return Z1 = log(F1), and Z2 = log( 1 + F2/F1). ++ The values of log(F1) are calculated beforehand and stored ++ in the program. ++ */ ++ ++ f = x; ++ ++ /* Store the exponent of x in xexp and put ++ f into the range [0.5,1) */ ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64; ++ PUT_BITS_DP64((ux & MANTBITS_DP64) | HALFEXPBITS_DP64, f); ++ ++ /* Now x = 2**xexp * f, 1/2 <= f < 1. */ ++ ++ /* Set index to be the nearest integer to 128*f */ ++ /* ++ r = 128.0 * f; ++ index = (int)(r + 0.5); ++ */ ++ /* This code instead of the above can save several cycles. ++ It only works because 64 <= r < 128, so ++ the nearest integer is always contained in exactly ++ 7 bits, and the right shift is always the same. */ ++ index = (((ux & 0x000fc00000000000) | 0x0010000000000000) >> 46) ++ + ((ux & 0x0000200000000000) >> 45); ++ z1 = ln_lead_table[index-64]; ++ q = ln_tail_table[index-64]; ++ f1 = index * 0.0078125; /* 0.0078125 = 1/128 */ ++ f2 = f - f1; ++ /* At this point, x = 2**xexp * ( f1 + f2 ) where ++ f1 = j/128, j = 64, 65, ..., 128 and |f2| <= 1/256. */ ++ ++ /* Calculate u = 2 f2 / ( 2 f1 + f2 ) = f2 / ( f1 + 0.5*f2 ) */ ++ /* u = f2 / (f1 + 0.5 * f2); */ ++ u = f2 / (f1 + 0.5 * f2); ++ ++ /* Here, |u| <= 2(exp(1/16)-1) / (exp(1/16)+1). ++ The core approximation calculates ++ poly = [log(1 + u/2) - log(1 - u/2)]/u - 1 */ ++ v = u * u; ++ poly = (v * (cb_1 + v * cb_2)); ++ z2 = q + (u + u * poly); ++ ++ /* Now z1,z2 is an extra-precise approximation of log(f). ++ Add xexp * log(2) to z1, z2 to get the result log(x). */ ++ ++ r = xexp*log2 + z1 + z2; ++#if defined (COMPILING_LOG10) ++ return log10e*r; ++#elif defined(COMPILING_LOG2) ++ return log2e*r; ++#else ++ return r; ++#endif ++} ++ ++#if defined(COMPILING_LOG10) ++weak_alias (__log10f, log10f) ++weak_alias (__log10f, __ieee754_log10f) ++#elif defined(COMPILING_LOG2) ++weak_alias (__log2f, log2f) ++weak_alias (__log2f, __ieee754_log2f) ++#else ++weak_alias (__logf, logf) ++weak_alias (__logf, __ieee754_logf) ++#endif +diff -urpN libc/sysdeps/x86_64/fpu/w_pow.c libc-amd/sysdeps/x86_64/fpu/w_pow.c +--- libc/sysdeps/x86_64/fpu/w_pow.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_pow.c 2006-03-22 02:30:12.000000000 +0100 +@@ -0,0 +1,808 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_2 ++#define USE_SCALEDOUBLE_3 ++#define USE_SCALEDOWNDOUBLE ++#define USE_INFINITY_WITH_FLAGS ++#define USE_ZERO_WITH_FLAGS ++#define USE_NAN_WITH_FLAGS ++#define USE_VAL_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_2 ++#undef USE_SCALEDOUBLE_3 ++#undef USE_SCALEDOWNDOUBLE ++#undef USE_INFINITY_WITH_FLAGS ++#undef USE_ZERO_WITH_FLAGS ++#undef USE_NAN_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange_overflow(double x, double y, int sign) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = y; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"pow"; ++ if (_LIB_VERSION == _SVID_) ++ { ++ if (sign == 1) ++ exc.retval = HUGE; ++ else /* sign = -1 */ ++ exc.retval = -HUGE; ++ } ++ else ++ { ++ if (sign == 1) ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW); ++ else /* sign == -1 */ ++ exc.retval = -infinity_with_flags(AMD_F_OVERFLOW); ++ } ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline double retval_errno_erange_underflow(double x, double y, int sign) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = y; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"pow"; ++ if (sign == 1) ++ exc.retval = zero_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ else /* sign == -1 */ ++ exc.retval = -zero_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++/* Deal with errno for out-of-range arguments */ ++static inline double retval_errno_edom(double x, double y, int type) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = y; ++ exc.type = DOMAIN; ++ exc.name = (char *)"pow"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = 0.0; ++ else if (type == 1) ++ exc.retval = infinity_with_flags(AMD_F_DIVBYZERO); ++ else if (type == 2) ++ exc.retval = -infinity_with_flags(AMD_F_DIVBYZERO); ++ else /* type == 3 */ ++ exc.retval = nan_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno (EDOM); ++ if (!matherr(&exc)) ++ { ++ if (_LIB_VERSION == _SVID_) ++ (void)fputs("pow: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++/* Computes the exact product of x and y, the result being the ++ nearly doublelength number (z,zz) */ ++static void mul12(double x, double y, ++ double *z, double *zz) ++{ ++ double hx, tx, hy, ty; ++ /* Split x into hx (head) and tx (tail). Do the same for y. */ ++ unsigned long u; ++ GET_BITS_DP64(x, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hx); ++ tx = x - hx; ++ GET_BITS_DP64(y, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hy); ++ ty = y - hy; ++ *z = x * y; ++ *zz = (((hx * hy - *z) + hx * ty) + tx * hy) + tx * ty; ++} ++ ++/* Computes the doublelength product of (x,xx) and (y,yy), the result ++ being the doublelength number (z,zz) */ ++static void mul2(double x, double xx, double y, double yy, ++ double *z, double *zz) ++{ ++ double c, cc; ++ mul12(x, y, &c, &cc); ++ cc = x * yy + xx * y + cc; ++ *z = c + cc; ++ *zz = (c - *z) + cc; ++} ++ ++double __pow(double x, double y) ++{ ++ ++ /* Arrays log2_lead_table and log2_tail_table contain ++ leading and trailing parts respectively of precomputed ++ values of natural log2(1+i/64), for i = 0, 1, ..., 64. ++ ln_lead_table contains the first 24 bits of precision, ++ and ln_tail_table contains a further 53 bits precision. */ ++ ++ static const double log2_lead_table[65] = { ++ 0.00000000000000000000E+00, /* 0x0000000000000000 */ ++ 2.23678126931190490723E-02, /* 0x3F96E79680000000 */ ++ 4.43941168487071990967E-02, /* 0x3FA6BAD360000000 */ ++ 6.60891830921173095703E-02, /* 0x3FB0EB3880000000 */ ++ 8.74628350138664245605E-02, /* 0x3FB663F6E0000000 */ ++ 1.08524456620216369629E-01, /* 0x3FBBC84240000000 */ ++ 1.29283010959625244141E-01, /* 0x3FC08C5880000000 */ ++ 1.49747118353843688965E-01, /* 0x3FC32AE9E0000000 */ ++ 1.69924989342689514160E-01, /* 0x3FC5C01A20000000 */ ++ 1.89824551343917846680E-01, /* 0x3FC84C2BC0000000 */ ++ 2.09453359246253967285E-01, /* 0x3FCACF5E20000000 */ ++ 2.28818684816360473633E-01, /* 0x3FCD49EE40000000 */ ++ 2.47927501797676086426E-01, /* 0x3FCFBC16A0000000 */ ++ 2.66786515712738037109E-01, /* 0x3FD11307C0000000 */ ++ 2.85402208566665649414E-01, /* 0x3FD24407A0000000 */ ++ 3.03780734539031982422E-01, /* 0x3FD37124C0000000 */ ++ 3.21928083896636962891E-01, /* 0x3FD49A7840000000 */ ++ 3.39849978685379028320E-01, /* 0x3FD5C01A20000000 */ ++ 3.57551991939544677734E-01, /* 0x3FD6E221C0000000 */ ++ 3.75039428472518920898E-01, /* 0x3FD800A560000000 */ ++ 3.92317414283752441406E-01, /* 0x3FD91BBA80000000 */ ++ 4.09390926361083984375E-01, /* 0x3FDA337600000000 */ ++ 4.26264733076095581055E-01, /* 0x3FDB47EBE0000000 */ ++ 4.42943483591079711914E-01, /* 0x3FDC592FA0000000 */ ++ 4.59431618452072143555E-01, /* 0x3FDD6753E0000000 */ ++ 4.75733429193496704102E-01, /* 0x3FDE726AA0000000 */ ++ 4.91853088140487670898E-01, /* 0x3FDF7A8560000000 */ ++ 5.07794618606567382812E-01, /* 0x3FE03FDA80000000 */ ++ 5.23561954498291015625E-01, /* 0x3FE0C10500000000 */ ++ 5.39158761501312255859E-01, /* 0x3FE140C9E0000000 */ ++ 5.54588794708251953125E-01, /* 0x3FE1BF3100000000 */ ++ 5.69855570793151855469E-01, /* 0x3FE23C41C0000000 */ ++ 5.84962487220764160156E-01, /* 0x3FE2B80340000000 */ ++ 5.99912822246551513672E-01, /* 0x3FE3327C60000000 */ ++ 6.14709794521331787109E-01, /* 0x3FE3ABB3E0000000 */ ++ 6.29356563091278076172E-01, /* 0x3FE423B060000000 */ ++ 6.43856167793273925781E-01, /* 0x3FE49A7840000000 */ ++ 6.58211469650268554688E-01, /* 0x3FE5101180000000 */ ++ 6.72425329685211181641E-01, /* 0x3FE5848220000000 */ ++ 6.86500489711761474609E-01, /* 0x3FE5F7CFE0000000 */ ++ 7.00439691543579101562E-01, /* 0x3FE66A0080000000 */ ++ 7.14245498180389404297E-01, /* 0x3FE6DB1960000000 */ ++ 7.27920413017272949219E-01, /* 0x3FE74B1FC0000000 */ ++ 7.41466939449310302734E-01, /* 0x3FE7BA18E0000000 */ ++ 7.54887461662292480469E-01, /* 0x3FE82809C0000000 */ ++ 7.68184304237365722656E-01, /* 0x3FE894F740000000 */ ++ 7.81359672546386718750E-01, /* 0x3FE900E600000000 */ ++ 7.94415831565856933594E-01, /* 0x3FE96BDAC0000000 */ ++ 8.07354867458343505859E-01, /* 0x3FE9D5D9E0000000 */ ++ 8.20178925991058349609E-01, /* 0x3FEA3EE7E0000000 */ ++ 8.32889974117279052734E-01, /* 0x3FEAA708E0000000 */ ++ 8.45490038394927978516E-01, /* 0x3FEB0E4120000000 */ ++ 8.57980966567993164062E-01, /* 0x3FEB749480000000 */ ++ 8.70364665985107421875E-01, /* 0x3FEBDA0700000000 */ ++ 8.82643043994903564453E-01, /* 0x3FEC3E9CA0000000 */ ++ 8.94817709922790527344E-01, /* 0x3FECA258C0000000 */ ++ 9.06890571117401123047E-01, /* 0x3FED053F60000000 */ ++ 9.18863236904144287109E-01, /* 0x3FED6753E0000000 */ ++ 9.30737316608428955078E-01, /* 0x3FEDC899A0000000 */ ++ 9.42514479160308837891E-01, /* 0x3FEE291420000000 */ ++ 9.54196274280548095703E-01, /* 0x3FEE88C6A0000000 */ ++ 9.65784251689910888672E-01, /* 0x3FEEE7B460000000 */ ++ 9.77279901504516601562E-01, /* 0x3FEF45E080000000 */ ++ 9.88684654235839843750E-01, /* 0x3FEFA34E00000000 */ ++ 1.00000000000000000000E+00}; /* 0x3FF0000000000000 */ ++ ++ static const double log2_tail_table[65] = { ++ 0.00000000000000000000E+00, /* 0x0000000000000000 */ ++ 3.35335459194866276130E-10, /* 0x3DF70B48A629B89C */ ++ 2.50974623855642191448E-09, /* 0x3E258EFD87313606 */ ++ 7.36565512335896390543E-09, /* 0x3E3FA29F9AB3CF74 */ ++ 6.23647298369351871453E-09, /* 0x3E3AC913167CCC53 */ ++ 1.57952684118980398844E-10, /* 0x3DE5B5774C7658A0 */ ++ 5.98534121117166302413E-09, /* 0x3E39B4F3C72C4F78 */ ++ 1.15083837244190179789E-09, /* 0x3E13C570D0FA8F90 */ ++ 1.20996228487473215213E-08, /* 0x3E49FBD6879FA00B */ ++ 7.53609938318432874467E-09, /* 0x3E402F03B2FDD224 */ ++ 6.38269581457264661091E-09, /* 0x3E3B69D927DFC23C */ ++ 5.67952040356156465017E-09, /* 0x3E3864B2DF91E96A */ ++ 1.16459094073677371864E-08, /* 0x3E4902680A23A8D9 */ ++ 2.49821633265319561946E-08, /* 0x3E5AD30B75CB0970 */ ++ 1.02955826924364881206E-08, /* 0x3E461C0E73048B72 */ ++ 1.36380709420054099385E-08, /* 0x3E4D499BD9B32266 */ ++ 1.09907253849796912371E-08, /* 0x3E479A3715FC9256 */ ++ 2.41992456974946430426E-08, /* 0x3E59FBD6879FA00B */ ++ 1.26785390154315961619E-08, /* 0x3E4B3A19BCAF1AA4 */ ++ 2.87440583546118995874E-09, /* 0x3E28B0E2A19575B0 */ ++ 8.49500784748945819113E-09, /* 0x3E423E2E1169656A */ ++ 9.77661777174938265384E-09, /* 0x3E44FEC0A13AF880 */ ++ 2.16260023578294509223E-08, /* 0x3E573882A0A4146E */ ++ 1.22576485902594488001E-08, /* 0x3E4A52B6ACFCFDCA */ ++ 1.85225112644675216321E-10, /* 0x3DE975077F1F5F00 */ ++ 1.77290105086271740075E-09, /* 0x3E1E754D20C519E0 */ ++ 8.18918703987935816281E-09, /* 0x3E41960D9D9C3262 */ ++ 2.15921288850262793860E-08, /* 0x3E572F32FE672868 */ ++ 1.55872185666914610882E-09, /* 0x3E1AC754CB104AE0 */ ++ 4.96067191344004864525E-08, /* 0x3E6AA1E5439E15A5 */ ++ 5.69693854190458063634E-08, /* 0x3E6E95D00DE3B513 */ ++ 3.75377959861950863279E-08, /* 0x3E642727C8080ECC */ ++ 1.35003920212974864041E-08, /* 0x3E4CFDEB43CFD004 */ ++ 1.99405761661543437744E-08, /* 0x3E5569394D90D724 */ ++ 4.95938764277745619566E-08, /* 0x3E6AA02166CCCAB2 */ ++ 5.69883315429349605246E-08, /* 0x3E6E986AA9670761 */ ++ 2.19814507699593824742E-08, /* 0x3E579A3715FC9256 */ ++ 1.31015261824841576777E-08, /* 0x3E4C22A3E377A524 */ ++ 1.22862844080671745121E-08, /* 0x3E4A6274CF0E362C */ ++ 3.74714569064514928410E-08, /* 0x3E641E09AEB8CB1A */ ++ 2.65975130588343109077E-08, /* 0x3E5C8F11979A5DB6 */ ++ 1.94857332324691494283E-08, /* 0x3E54EC3293B2FBE0 */ ++ 4.15459262300620263689E-08, /* 0x3E664E0753C6E578 */ ++ 4.69518366451302198484E-08, /* 0x3E693502E409EAB7 */ ++ 4.05011760638924658298E-08, /* 0x3E65BE7072DBDC04 */ ++ 2.05395606358225316367E-08, /* 0x3E560DDF1680DD44 */ ++ 4.09782728853196822622E-08, /* 0x3E660002CCFE43F5 */ ++ 3.47842490297177925737E-08, /* 0x3E62ACB5F5EFEC49 */ ++ 5.45992606015825934783E-08, /* 0x3E6D5010B3666559 */ ++ 3.64241293587091694274E-08, /* 0x3E638E181ED0798D */ ++ 4.00474626225128781862E-08, /* 0x3E658014D37CDE37 */ ++ 1.25494472416488406547E-08, /* 0x3E4AF321AF5E9BB4 */ ++ 2.85595789566572715872E-08, /* 0x3E5EAA65B49696E2 */ ++ 5.35982971014292903334E-08, /* 0x3E6CC67E6DB516DE */ ++ 5.36693769435427990824E-09, /* 0x3E370D02A99B4C58 */ ++ 5.33851529883522815863E-08, /* 0x3E6CA9331635FEE3 */ ++ 2.44911174062771809500E-08, /* 0x3E5A4C112CE6312E */ ++ 3.70450225289350432643E-10, /* 0x3DF975077F1F5F00 */ ++ 2.09544573213940723936E-08, /* 0x3E567FEAD8BCCE74 */ ++ 2.61789310367290825660E-08, /* 0x3E5C1C02803F7554 */ ++ 3.61063271131029934309E-08, /* 0x3E63626A72AA21A3 */ ++ 3.29721761549390770201E-08, /* 0x3E61B3A9507D6DC1 */ ++ 2.19953998687869412865E-08, /* 0x3E579E0CAA9C9AB6 */ ++ 3.25363260095299997864E-08, /* 0x3E6177C23362928B */ ++ 0.00000000000000000000E+00}; /* 0x0000000000000000 */ ++ ++ static const double ++ /* Reciprocal of log(2.0) */ ++ reclog2_lead = 1.44269504088896338700E+00, /* 0x3FF71547652B82FE */ ++ reclog2_tail = 2.03552737409310207851E-17; /* 0x3C7777D0FFDA0D20 */ ++ ++ const double large = 1.79769313486231570815e+308; /* 0x7fefffffffffffff */ ++ ++ unsigned long ux, ax, uy, ay, mask; ++ int yexp, inty, xpos, ypos, negateres; ++ double r, u1, u2, w, w1, w2; ++ volatile int dummy; ++ ++ double u, r1, r2, f, z1, z2, q, f1, f2, poly; ++ int xexp, expadjust, index, iw; ++ ++ double argx = x, argy = y; ++ ++ GET_BITS_DP64(x, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ xpos = ax == ux; ++ GET_BITS_DP64(y, uy); ++ ay = uy & (~SIGNBIT_DP64); ++ ypos = ay == uy; ++ ++ if (ux == 0x3ff0000000000000) ++ { ++ /* x = +1.0. Return +1.0 for all y, even NaN, ++ raising invalid only if y is a signalling NaN */ ++ if (y + 1.0 == 2.0) dummy = 1; ++ return 1.0; ++ } ++ else if (ay == 0) ++ { ++ /* y is zero. Return 1.0, even if x is infinity or NaN, ++ raising invalid only if x is a signalling NaN */ ++ if (x + 1.0 == 2.0) dummy = 1; ++ return 1.0; ++ } ++ else if (((ax & EXPBITS_DP64) == EXPBITS_DP64) && ++ (ax & MANTBITS_DP64)) ++ /* x is NaN. Return NaN, with invalid exception if it's ++ a signalling NaN. */ ++ return x + x; ++ else if (((ay & EXPBITS_DP64) == EXPBITS_DP64) && ++ (ay & MANTBITS_DP64)) ++ /* y is NaN. Return NaN, with invalid exception if y ++ is a signalling NaN. */ ++ return y + y; ++ else if (uy == 0x3ff0000000000000) ++ /* y is 1.0; return x */ ++ return x; ++ else if ((ay & EXPBITS_DP64) > 0x43e0000000000000) ++ { ++ /* y is infinite or so large that the result would ++ overflow or underflow. Flags should be raised ++ unless y is an exact infinity. */ ++ int yinf = (ay == EXPBITS_DP64); ++ if (ypos) ++ { ++ /* y is +ve */ ++ if (ax == 0) ++ /* abs(x) = 0.0. */ ++ return 0.0; ++ else if (ax < 0x3ff0000000000000) ++ { ++ /* abs(x) < 1.0 */ ++ if (yinf) ++ return 0.0; ++ else ++ return retval_errno_erange_underflow(argx, argy, 1); ++ } ++ else if (ax == 0x3ff0000000000000) ++ /* abs(x) = 1.0. */ ++ return 1.0; ++ else ++ { ++ /* abs(x) > 1.0 */ ++ if (yinf) ++ return infinity_with_flags(0); ++ else ++ return retval_errno_erange_overflow(argx, argy, 1); ++ } ++ } ++ else ++ { ++ /* y is -ve */ ++ if (ax == 0) ++ /* abs(x) = 0.0. Return +infinity. */ ++ return retval_errno_edom(argx, argy, 1); ++ else if (ax < 0x3ff0000000000000) ++ { ++ /* abs(x) < 1.0; return +infinity. */ ++ if (yinf) ++ return infinity_with_flags(0); ++ else ++ return retval_errno_erange_overflow(argx, argy, 1); ++ } ++ else if (ax == 0x3ff0000000000000) ++ /* abs(x) = 1.0. */ ++ return 1.0; ++ else ++ { ++ /* abs(x) > 1.0 */ ++ if (yinf) ++ return 0.0; ++ else ++ return retval_errno_erange_underflow(argx, argy, 1); ++ } ++ } ++ } ++ ++ /* See whether y is an integer. ++ inty = 0 means not an integer. ++ inty = 1 means odd integer. ++ inty = 2 means even integer. ++ */ ++ yexp = ((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64 + 1; ++ if (yexp < 1) ++ inty = 0; ++ else if (yexp > 53) ++ inty = 2; ++ else /* 1 <= yexp <= 53 */ ++ { ++ /* Mask out the bits of r that we don't want */ ++ mask = (1L << (53 - yexp)) - 1; ++ if ((uy & mask) != 0) ++ inty = 0; ++ else if (((uy & ~mask) >> (53 - yexp)) & 0x0000000000000001) ++ inty = 1; ++ else ++ inty = 2; ++ } ++ ++ if ((ax & EXPBITS_DP64) == EXPBITS_DP64) ++ { ++ /* x is infinity (NaN was already ruled out). */ ++ if (xpos) ++ { ++ /* x is +infinity */ ++ if (ypos) ++ /* y > 0.0 */ ++ return x; ++ else ++ return 0.0; ++ } ++ else ++ { ++ /* x is -infinity */ ++ if (inty == 1) ++ { ++ /* y is an odd integer */ ++ if (ypos) ++ /* Result is -infinity */ ++ return x; ++ else ++ return -zero_with_flags(0); ++ } ++ else ++ { ++ if (ypos) ++ /* Result is +infinity */ ++ return -x; ++ else ++ return 0.0; ++ } ++ } ++ } ++ else if (ax == 0) ++ { ++ /* x is zero */ ++ if (xpos) ++ { ++ /* x is +0.0 */ ++ if (ypos) ++ /* y is positive; return +0.0 for all cases */ ++ return x; ++ else ++ /* y is negative; return +infinity with div-by-zero ++ for all cases */ ++ return retval_errno_edom(argx, argy, 1); ++ } ++ else ++ { ++ /* x is -0.0 */ ++ if (ypos) ++ { ++ /* y is positive */ ++ if (inty == 1) ++ /* -0.0 raised to a positive odd integer returns -0.0 */ ++ return x; ++ else ++ /* Return +0.0 */ ++ return -x; ++ } ++ else ++ { ++ /* y is negative */ ++ if (inty == 1) ++ /* -0.0 raised to a negative odd integer returns -infinity ++ with div-by-zero */ ++ return retval_errno_edom(argx, argy, 2); ++ else ++ /* Return +infinity with div-by-zero */ ++ return retval_errno_edom(argx, argy, 1); ++ } ++ } ++ } ++ ++ negateres = 0; ++ if (!xpos) ++ { ++ /* x is negative */ ++ if (inty) ++ { ++ /* It's OK because y is an integer. */ ++ ux = ax; ++ PUT_BITS_DP64(ux, x); /* x = abs(x) */ ++ /* If y is odd, the result will be negative */ ++ negateres = (inty == 1); ++ } ++ else ++ /* y is not an integer. Return a NaN. */ ++ return retval_errno_edom(argx, argy, 3); ++ } ++ ++ if (ay < 0x3c00000000000000) /* abs(y) < 2^(-63) */ ++ { ++ /* y is close enough to zero for the result to be 1.0 ++ no matter what the size of x */ ++ return 1.0 + y; ++ } ++ ++ /* ++ Calculate log2(x) ++ ++ First, we decompose the argument x to the form ++ x = 2**M * (F1 + F2), ++ where 1 <= F1+F2 < 2, M has the value of an integer, ++ F1 = 1 + j/64, j ranges from 0 to 64, and |F2| <= 1/128. ++ ++ Second, we approximate log2( 1 + F2/F1 ) by a polynomial ++ in U, where U = 2 F2 / (2 F1 + F2). ++ Note that log2( 1 + F2/F1 ) = log2( 1 + U/2 ) - log2( 1 - U/2 ). ++ The core approximation calculates ++ Poly = [log2( 1 + U/2 ) - log2( 1 - U/2 )]/U - 1. ++ ++ It is not hard to see that ++ log2(x) = M + log2(F1) + log2( 1 + F2/F1 ). ++ Hence, we return Z1 = log2(F1), and Z2 = log2( 1 + F2/F1). ++ The values of log2(F1) are calculated beforehand and stored ++ in the program. ++ */ ++ ++ if (ux < IMPBIT_DP64) ++ { ++ /* The input argument x is denormalized */ ++ /* Normalize f by increasing the exponent by 60 ++ and subtracting a correction to account for the implicit ++ bit. This replaces a slow denormalized ++ multiplication by a fast normal subtraction. */ ++ static const double corr = 2.5653355008114851558350183e-290; /* 0x03d0000000000000 */ ++ PUT_BITS_DP64(ux | 0x03d0000000000000, f); ++ f -= corr; ++ GET_BITS_DP64(f, ux); ++ expadjust = 60; ++ } ++ else ++ { ++ f = x; ++ expadjust = 0; ++ } ++ ++ /* Store the exponent of x in xexp and put ++ f into the range [0.5,1) */ ++ xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64 - expadjust; ++ PUT_BITS_DP64((ux & MANTBITS_DP64) | HALFEXPBITS_DP64, f); ++ ++ /* Now x = 2**xexp * f, 1/2 <= f < 1. */ ++ ++ /* Set index to be the nearest integer to 128*f */ ++ /* ++ r = 128.0 * f; ++ index = (int)(r + 0.5); ++ */ ++ /* This code instead of the above can save several cycles. ++ It only works because 64 <= r < 128, so ++ the nearest integer is always contained in exactly ++ 7 bits, and the right shift is always the same. */ ++ index = (((ux & 0x000fc00000000000) | 0x0010000000000000) >> 46) ++ + ((ux & 0x0000200000000000) >> 45); ++ ++ z1 = log2_lead_table[index-64]; ++ q = log2_tail_table[index-64]; ++ f1 = index * 0.0078125; /* 0.0078125 = 1/128 */ ++ f2 = f - f1; ++ /* At this point, x = 2**xexp * ( f1 + f2 ) where ++ f1 = j/128, j = 64, 65, ..., 128 and |f2| <= 1/256. */ ++ ++ /* Compute z2 from Taylor series of log2(1+f1/f2) */ ++ ++ u = f2/f1; ++#if 0 ++ div2(f2,0.0,f1,0.0,&r1,&r2); ++#else ++ { ++ double cc, h, hh; ++ mul12(u, f1, &h, &hh); ++ cc = ((f2 - h) - hh) / f1; ++ r1 = u + cc; ++ r2 = (u - r1) + cc; ++ } ++#endif ++ poly = -u*(u*(1./2.-u*(1./3.-u* ++ (1./4.-u*(1./5.-u*(1./6.-u* ++ (1./7.-u*(1./8.)))))))); ++#if 0 ++ add2(r1,r2,poly,0.0,&r1,&r2); ++#else ++ { ++ double r, s; ++ r = r1 + poly; ++ s = ((r1 - r) + poly) + r2; ++ r1 = r + s; ++ r2 = (r - r1) + s; ++ } ++#endif ++ ++ mul2(reclog2_lead,reclog2_tail,r1,r2,&r1,&r2); ++ ++#if 0 ++ add2(r1,r2,q,0.0,&r1,&r2); ++#else ++ { ++ if (r1 == 0.0) ++ r1 = q; ++ else if (q != 0.0) ++ { ++ double r, s; ++ r = r1 + q; ++ s = ((r1 - r) + q) + r2; ++ r1 = r + s; ++ r2 = (r - r1) + s; ++ } ++ } ++#endif ++ ++#if 0 ++ add2(z1,0.0,r1,r2,&z1,&z2); ++#else ++ { ++ double r, s; ++ r = z1 + r1; ++ s = ((z1 - r) + r1) + r2; ++ z1 = r + s; ++ z2 = (r - z1) + s; ++ } ++#endif ++ ++ /* Now z1,z2 is an extra-precise approximation of log2(2f). ++ Add xexp to z1,z2 to get the result log2(x). ++ The computed r1 is not subject to rounding error because ++ xexp has at most 10 significant bits, log(2) has 24 significant ++ bits, and z1 has up to 24 bits; and the exponents of z1 ++ and z2 differ by at most 6. */ ++ ++#if 0 ++ add2(z1,z2,xexp,0.0,&u1,&u2); ++#else ++ { ++ double r, s; ++ r = z1 + xexp; ++ s = ((xexp - r) + z1) + z2; ++ u1 = r + s; ++ u2 = (r - u1) + s; ++ } ++#endif ++ ++ /* end of log2(x) calculation*/ ++ ++ /* Test for overflow and underflow due to y*log2(x) ++ being too large or small. */ ++ ++ if ((u1+u2)*y > 1025) ++ { ++ if (negateres) ++ return retval_errno_erange_overflow(argx, argy, -1); ++ else ++ return retval_errno_erange_overflow(argx, argy, 1); ++ } ++ else if ((u1+u2)*y < -1074) ++ { ++ if (negateres) ++ return retval_errno_erange_underflow(argx, argy, -1); ++ else ++ return retval_errno_erange_underflow(argx, argy, 1); ++ } ++ ++ /* Carefully compute log2(x) * y */ ++#if 0 ++ mul2(u1, u2, y, 0.0, &w1, &w2); ++#else ++ { ++ double c, cc; ++ mul12(u1, y, &c, &cc); ++ cc = u2 * y + cc; ++ w1 = c + cc; ++ w2 = (c - w1) + cc; ++ } ++#endif ++ ++ w = w1 + w2; ++ iw = (int)(w); ++ ++#if 0 ++ sub2(w1, w2, (double)iw, 0.0, &w1, &w2); ++#else ++ { ++ double a, b; ++ a = w1 - iw; ++ b = ((w1 - a) - iw) + w2; ++ w1 = a + b; ++ w2 = (a - w1) + b; ++ } ++#endif ++ ++ w = w1 + w2; ++ ++ /* The following code computes r = exp2(w) */ ++ ++ { ++ static const double ++ log2 = 6.931471805599453094178e-01, /* 0x3fe62e42fefa39ef */ ++ log2_lead = 6.93147167563438415527E-01, /* 0x3fe62e42f8000000 */ ++ log2_tail = 1.29965068938898869640E-08, /* 0x3e4be8e7bcd5e4f1 */ ++ one_by_32_lead = 0.03125; ++ ++ double p, z1, z2, z, hx, tx, y1, y2; ++ int m, n; ++ ++ GET_BITS_DP64(w, ux); ++ ax = ux & (~SIGNBIT_DP64); ++ ++ /* Handle small arguments separately */ ++ if (ax < 0x3fb7154764ee6c2f) /* abs(x) < 1/(16*log2) */ ++ { ++ if (ax < 0x3c00000000000000) /* abs(x) < 2^(-63) */ ++ z = 1.0 + w; /* Raises inexact if x is non-zero */ ++ else ++ { ++ /* Split x into hx (head) and tx (tail). */ ++ unsigned long u; ++ hx = w; ++ GET_BITS_DP64(hx, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hx); ++ tx = w - hx; ++ /* Carefully multiply x by log2. y1 is the most significant ++ part of the result, and y2 the least significant part */ ++ y1 = w * log2_lead; ++ y2 = (((hx * log2_lead - y1) + hx * log2_tail) + ++ tx * log2_lead) + tx * log2_tail; ++ ++ p = y1 + y2; ++ z = (9.99564649780173690e-1 + ++ (1.61251249355268050e-5 + ++ (2.37986978239838493e-2 + ++ 2.68724774856111190e-7*p)*p)*p)/ ++ (9.99564649780173692e-1 + ++ (-4.99766199765151309e-1 + ++ (1.070876894098586184e-1 + ++ (-1.189773642681502232e-2 + ++ 5.9480622371960190616e-4*p)*p)*p)*p); ++ ++ z = ((z * y1) + (z * y2)) + 1.0; ++ } ++ r = scaleDouble_2(z, iw); ++ } ++ else ++ { ++ /* Find m, z1 and z2 such that exp2(x) = 2**m * (z1 + z2) */ ++ splitexp(w, log2, 32.0, one_by_32_lead, 0.0, &m, &z1, &z2); ++ ++ /* Scale (z1 + z2) by 2.0**(m + iw) */ ++ ++ n = m+iw; ++ z = z1+z2; ++ ++ if (n < -1022) ++ { /* Result will be denormalised after scaling ++ down by 2**n. Using scaleDownDouble instead ++ of scaleDouble_3 is faster in this case. */ ++ GET_BITS_DP64(z, ux); ++ scaleDownDouble(ux, -n, &ux); ++ PUT_BITS_DP64(ux, r); ++ } ++ else ++ r = scaleDouble_3(z, n); ++ } ++ } ++ ++ /* If r overflowed or underflowed we need to deal with errno */ ++ if (r > large) ++ { ++ /* Result has overflowed. */ ++ if (negateres) ++ return retval_errno_erange_overflow(argx, argy, -1); ++ else ++ return retval_errno_erange_overflow(argx, argy, 1); ++ } ++ else if (r == 0.0) ++ { ++ /* Result has underflowed. */ ++ if (negateres) ++ return retval_errno_erange_underflow(argx, argy, -1); ++ else ++ return retval_errno_erange_underflow(argx, argy, 1); ++ } ++ else ++ { ++ if (negateres) ++ return -r; ++ else ++ return r; ++ } ++} ++ ++weak_alias (__pow, pow) ++weak_alias (__pow, __ieee754_pow) +diff -urpN libc/sysdeps/x86_64/fpu/w_powf.c libc-amd/sysdeps/x86_64/fpu/w_powf.c +--- libc/sysdeps/x86_64/fpu/w_powf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_powf.c 2006-03-22 02:30:34.000000000 +0100 +@@ -0,0 +1,359 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_ZEROF_WITH_FLAGS ++#define USE_INFINITYF_WITH_FLAGS ++#define USE_NANF_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_ZEROF_WITH_FLAGS ++#undef USE_INFINITYF_WITH_FLAGS ++#undef USE_NANF_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange_overflow(float x, float y, int sign) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)y; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"powf"; ++ if (_LIB_VERSION == _SVID_) ++ { ++ if (sign == 1) ++ exc.retval = HUGE; ++ else /* sign = -1 */ ++ exc.retval = -HUGE; ++ } ++ else ++ { ++ if (sign == 1) ++ exc.retval = infinityf_with_flags(AMD_F_OVERFLOW); ++ else /* sign == -1 */ ++ exc.retval = -infinityf_with_flags(AMD_F_OVERFLOW); ++ } ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++static inline float retval_errno_erange_underflow(float x, float y, int sign) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)y; ++ exc.type = UNDERFLOW; ++ exc.name = (char *)"powf"; ++ if (sign == 1) ++ exc.retval = zerof_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ else /* sign == -1 */ ++ exc.retval = -zerof_with_flags(AMD_F_UNDERFLOW | AMD_F_INEXACT); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++/* Deal with errno for out-of-range arguments */ ++static inline float retval_errno_edom(float x, float y, int type) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)y; ++ exc.type = DOMAIN; ++ exc.name = (char *)"powf"; ++ if (_LIB_VERSION == _SVID_) ++ exc.retval = 0.0; ++ else if (type == 1) ++ exc.retval = infinityf_with_flags(AMD_F_DIVBYZERO); ++ else if (type == 2) ++ exc.retval = -infinityf_with_flags(AMD_F_DIVBYZERO); ++ else /* type == 3 */ ++ exc.retval = nanf_with_flags(AMD_F_INVALID); ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno (EDOM); ++ if (!matherr(&exc)) ++ { ++ if (_LIB_VERSION == _SVID_) ++ (void)fputs("pow: DOMAIN error\n", stderr); ++ __set_errno(EDOM); ++ } ++ return exc.retval; ++} ++ ++float __powf(float x, float y) ++{ ++ unsigned int ux, ax, uy, ay, mask; ++ int yexp, inty, xpos, ypos, negateres; ++ double dx, dy, dw, dlog2, dr; ++ volatile int dummy; ++ ++ /* Largest float, stored as a double */ ++ const double large = 3.40282346638528859812e+38; /* 0x47efffffe0000000 */ ++ ++ /* Smallest float, stored as a double */ ++ const double tiny = 1.40129846432481707092e-45; /* 0x36a0000000000000 */ ++ ++ GET_BITS_SP32(x, ux); ++ ax = ux & (~SIGNBIT_SP32); ++ xpos = ax == ux; ++ GET_BITS_SP32(y, uy); ++ ay = uy & (~SIGNBIT_SP32); ++ ypos = ay == uy; ++ ++ if (ux == 0x3f800000) ++ { ++ /* x = +1.0. Return +1.0 for all y, even NaN, ++ raising invalid only if y is a signalling NaN */ ++ if (y + 1.0F == 2.0F) dummy = 1; ++ return 1.0F; ++ } ++ else if (ay == 0) ++ { ++ /* y is zero. Return 1.0, even if x is infinity or NaN, ++ raising invalid only if x is a signalling NaN */ ++ if (x + 1.0F == 2.0F) dummy = 1; ++ return 1.0F; ++ } ++ else if (((ax & EXPBITS_SP32) == EXPBITS_SP32) && ++ (ax & MANTBITS_SP32)) ++ /* x is NaN. Return NaN, with invalid exception if it's ++ a signalling NaN. */ ++ return x + x; ++ else if (((ay & EXPBITS_SP32) == EXPBITS_SP32) && ++ (ay & MANTBITS_SP32)) ++ /* y is NaN. Return NaN, with invalid exception if y ++ is a signalling NaN. */ ++ return y + y; ++ else if (uy == 0x3f800000) ++ /* y is 1.0; return x */ ++ return x; ++ else if ((ay & EXPBITS_SP32) > 0x4f000000) ++ { ++ /* y is infinite or so large that the result would ++ overflow or underflow. Flags should be raised ++ unless y is an exact infinity. */ ++ int yinf = (ay == EXPBITS_SP32); ++ if (ypos) ++ { ++ /* y is +ve */ ++ if (ax == 0) ++ /* abs(x) = 0.0. */ ++ return 0.0F; ++ else if (ax < 0x3f800000) ++ { ++ /* abs(x) < 1.0 */ ++ if (yinf) ++ return 0.0F; ++ else ++ return retval_errno_erange_underflow(x, y, 1); ++ } ++ else if (ax == 0x3f800000) ++ /* abs(x) = 1.0. */ ++ return 1.0F; ++ else ++ { ++ /* abs(x) > 1.0 */ ++ if (yinf) ++ return infinityf_with_flags(0); ++ else ++ return retval_errno_erange_overflow(x, y, 1); ++ } ++ } ++ else ++ { ++ /* y is -ve */ ++ if (ax == 0) ++ /* abs(x) = 0.0. Return +infinity. */ ++ return retval_errno_edom(x, y, 1); ++ else if (ax < 0x3f800000) ++ { ++ /* abs(x) < 1.0; return +infinity. */ ++ if (yinf) ++ return infinityf_with_flags(0); ++ else ++ return retval_errno_erange_overflow(x, y, 1); ++ } ++ else if (ax == 0x3f800000) ++ /* abs(x) = 1.0. */ ++ return 1.0F; ++ else ++ { ++ /* abs(x) > 1.0 */ ++ if (yinf) ++ return 0.0F; ++ else ++ return retval_errno_erange_underflow(x, y, 1); ++ } ++ } ++ } ++ ++ /* See whether y is an integer. ++ inty = 0 means not an integer. ++ inty = 1 means odd integer. ++ inty = 2 means even integer. ++ */ ++ yexp = ((uy & EXPBITS_SP32) >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32 + 1; ++ if (yexp < 1) ++ inty = 0; ++ else if (yexp > 24) ++ inty = 2; ++ else /* 1 <= yexp <= 24 */ ++ { ++ /* Mask out the bits of r that we don't want */ ++ mask = (1 << (24 - yexp)) - 1; ++ if ((uy & mask) != 0) ++ inty = 0; ++ else if (((uy & ~mask) >> (24 - yexp)) & 0x00000001) ++ inty = 1; ++ else ++ inty = 2; ++ } ++ ++ if ((ax & EXPBITS_SP32) == EXPBITS_SP32) ++ { ++ /* x is infinity (NaN was already ruled out). */ ++ if (xpos) ++ { ++ /* x is +infinity */ ++ if (ypos) ++ /* y > 0.0 */ ++ return x; ++ else ++ return 0.0F; ++ } ++ else ++ { ++ /* x is -infinity */ ++ if (inty == 1) ++ { ++ /* y is an odd integer */ ++ if (ypos) ++ /* Result is -infinity */ ++ return x; ++ else ++ return -0.0F; ++ } ++ else ++ { ++ if (ypos) ++ /* Result is +infinity */ ++ return -x; ++ else ++ return 0.0F; ++ } ++ } ++ } ++ else if (ax == 0) ++ { ++ /* x is zero */ ++ if (xpos) ++ { ++ /* x is +0.0 */ ++ if (ypos) ++ /* y is positive; return +0.0 for all cases */ ++ return x; ++ else ++ /* y is negative; return +infinity with div-by-zero ++ for all cases */ ++ return retval_errno_edom(x, y, 1); ++ } ++ else ++ { ++ /* x is -0.0 */ ++ if (ypos) ++ { ++ /* y is positive */ ++ if (inty == 1) ++ /* -0.0 raised to a positive odd integer returns -0.0 */ ++ return x; ++ else ++ /* Return +0.0 */ ++ return -x; ++ } ++ else ++ { ++ /* y is negative */ ++ if (inty == 1) ++ /* -0.0 raised to a negative odd integer returns -infinity ++ with div-by-zero */ ++ return retval_errno_edom(x, y, 2); ++ else ++ /* Return +infinity with div-by-zero */ ++ return retval_errno_edom(x, y, 1); ++ } ++ } ++ } ++ ++ negateres = 0; ++ if (!xpos) ++ { ++ /* x is negative */ ++ if (inty) ++ { ++ /* It's OK because y is an integer. */ ++ ux = ax; ++ PUT_BITS_SP32(ux, x); /* x = abs(x) */ ++ /* If y is odd, the result will be negative */ ++ negateres = (inty == 1); ++ } ++ else ++ /* y is not an integer. Return a NaN. */ ++ return retval_errno_edom(x, y, 3); ++ } ++ ++ if (ay < 0x2e800000) /* abs(y) < 2^(-34) */ ++ { ++ /* y is close enough to zero for the result to be 1.0 ++ no matter what the size of x */ ++ return 1.0F + y; ++ } ++ ++ /* Simply use double precision for computation of log2(x), ++ y*log2(x) and exp2(y*log2(x)) */ ++ dx = x; ++ dy = y; ++ dlog2 = __log2(dx); ++ dw = y * dlog2; ++ dr = __exp2(dw); ++ ++ /* If dr overflowed or underflowed we need to deal with errno */ ++ if (dr > large) ++ { ++ /* Double dr has overflowed range of float. */ ++ if (negateres) ++ return retval_errno_erange_overflow(x, y, -1); ++ else ++ return retval_errno_erange_overflow(x, y, 1); ++ } ++ else if (dr < tiny) ++ { ++ /* Double dr has underflowed range of float. */ ++ if (negateres) ++ return retval_errno_erange_underflow(x, y, -1); ++ else ++ return retval_errno_erange_underflow(x, y, 1); ++ } ++ else ++ { ++ if (negateres) ++ return -dr; ++ else ++ return dr; ++ } ++} ++ ++weak_alias (__powf, powf) ++weak_alias (__powf, __ieee754_powf) +diff -urpN libc/sysdeps/x86_64/fpu/w_remainder.c libc-amd/sysdeps/x86_64/fpu/w_remainder.c +--- libc/sysdeps/x86_64/fpu/w_remainder.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_remainder.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,270 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_NAN_WITH_FLAGS ++#define USE_SCALEDOUBLE_3 ++#define USE_GET_FPSW_INLINE ++#define USE_SET_FPSW_INLINE ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_SCALEDOUBLE_3 ++#undef USE_GET_FPSW_INLINE ++#undef USE_SET_FPSW_INLINE ++ ++/* Computes the exact product of x and y, the result being the ++ nearly doublelength number (z,zz) */ ++static inline void dekker_mul12(double x, double y, ++ double *z, double *zz) ++{ ++ double hx, tx, hy, ty; ++ /* Split x into hx (head) and tx (tail). Do the same for y. */ ++ unsigned long u; ++ GET_BITS_DP64(x, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hx); ++ tx = x - hx; ++ GET_BITS_DP64(y, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hy); ++ ty = y - hy; ++ *z = x * y; ++ *zz = (((hx * hy - *z) + hx * ty) + tx * hy) + tx * ty; ++} ++ ++ ++#if defined(COMPILING_FMOD) ++double __fmod(double x, double y) ++#else ++double __remainder(double x, double y) ++#endif ++{ ++ double dx, dy, scale, w, t, v, c, cc; ++ int i, ntimes, xexp, yexp; ++ unsigned long u, ux, uy, ax, ay, todd; ++ unsigned int sw; ++ ++ dx = x; ++ dy = y; ++ ++ GET_BITS_DP64(dx, ux); ++ GET_BITS_DP64(dy, uy); ++ ax = ux & ~SIGNBIT_DP64; ++ ay = uy & ~SIGNBIT_DP64; ++ xexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ yexp = ((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ ++ if (xexp < 1 || xexp > BIASEDEMAX_DP64 || ++ yexp < 1 || yexp > BIASEDEMAX_DP64) ++ { ++ /* x or y is zero, denormalized, NaN or infinity */ ++ if (xexp > BIASEDEMAX_DP64) ++ { ++ /* x is NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return dx + dx; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity; result is NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ else if (yexp > BIASEDEMAX_DP64) ++ { ++ /* y is NaN or infinity */ ++ if (uy & MANTBITS_DP64) ++ /* y is NaN */ ++ return dy + dy; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* y is infinity; result is x */ ++ return dx; ++ } ++ else if (ax == 0x0000000000000000) ++ { ++ /* x is zero */ ++ if (ay == 0x0000000000000000) ++ /* y is zero */ ++ return nan_with_flags(AMD_F_INVALID); ++ else ++ return dx; ++ } ++ else if (ay == 0x0000000000000000) ++ /* y is zero */ ++ return nan_with_flags(AMD_F_INVALID); ++ ++ /* We've exhausted all other possibilities. One or both of x and ++ y must be denormalized */ ++ if (xexp < 1) ++ { ++ /* x is denormalized. Figure out its exponent. */ ++ u = ax; ++ while (u < IMPBIT_DP64) ++ { ++ xexp--; ++ u <<= 1; ++ } ++ } ++ if (yexp < 1) ++ { ++ /* y is denormalized. Figure out its exponent. */ ++ u = ay; ++ while (u < IMPBIT_DP64) ++ { ++ yexp--; ++ u <<= 1; ++ } ++ } ++ } ++ else if (ax == ay) ++ { ++ /* abs(x) == abs(y); return zero with the sign of x */ ++ PUT_BITS_DP64(ux & SIGNBIT_DP64, dx); ++ return dx; ++ } ++ ++ /* Set x = abs(x), y = abs(y) */ ++ PUT_BITS_DP64(ax, dx); ++ PUT_BITS_DP64(ay, dy); ++ ++ if (ax < ay) ++ { ++ /* abs(x) < abs(y) */ ++#if !defined(COMPILING_FMOD) ++ if (dx > 0.5*dy) ++ dx -= dy; ++#endif ++ return x < 0.0? -dx : dx; ++ } ++ ++ /* Save the current floating-point status word. We need ++ to do this because the remainder function is always ++ exact for finite arguments, but our algorithm causes ++ the inexact flag to be raised. We therefore need to ++ restore the entry status before exiting. */ ++ sw = get_fpsw_inline(); ++ ++ /* Set ntimes to the number of times we need to do a ++ partial remainder. If the exponent of x is an exact multiple ++ of 52 larger than the exponent of y, and the mantissa of x is ++ less than the mantissa of y, ntimes will be one too large ++ but it doesn't matter - it just means that we'll go round ++ the loop below one extra time. */ ++ if (xexp <= yexp) ++ ntimes = 0; ++ else ++ ntimes = (xexp - yexp) / 52; ++ ++ if (ntimes == 0) ++ { ++ w = dy; ++ scale = 1.0; ++ } ++ else ++ { ++ /* Set w = y * 2^(52*ntimes) */ ++ w = scaleDouble_3(dy, ntimes * 52); ++ ++ /* Set scale = 2^(-52) */ ++ PUT_BITS_DP64((unsigned long)(-52 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, ++ scale); ++ } ++ ++ /* Each time round the loop we compute a partial remainder. ++ This is done by subtracting a large multiple of w ++ from x each time, where w is a scaled up version of y. ++ The subtraction must be performed exactly in quad ++ precision, though the result at each stage can ++ fit exactly in a double precision number. */ ++ for (i = 0; i < ntimes; i++) ++ { ++ /* t is the integer multiple of w that we will subtract. ++ We use a truncated value for t. ++ ++ N.B. w has been chosen so that the integer t will have ++ at most 52 significant bits. This is the amount by ++ which the exponent of the partial remainder dx gets reduced ++ every time around the loop. In theory we could use ++ 53 bits in t, but the quad precision multiplication ++ routine dekker_mul12 does not allow us to do that because ++ it loses the last (106th) bit of its quad precision result. */ ++ ++ /* Set dx = dx - w * t, where t is equal to trunc(dx/w). */ ++ t = (double)(long)(dx / w); ++ /* At this point, t may be one too large due to ++ rounding of dx/w */ ++ ++ /* Compute w * t in quad precision */ ++ dekker_mul12(w, t, &c, &cc); ++ ++ /* Subtract w * t from dx */ ++ v = dx - c; ++ dx = v + (((dx - v) - c) - cc); ++ ++ /* If t was one too large, dx will be negative. Add back ++ one w */ ++ /* It might be possible to speed up this loop by finding ++ a way to compute correctly truncated t directly from dx and w. ++ We would then avoid the need for this check on negative dx. */ ++ if (dx < 0.0) ++ dx += w; ++ ++ /* Scale w down by 2^(-52) for the next iteration */ ++ w *= scale; ++ } ++ ++ /* One more time */ ++ /* Variable todd says whether the integer t is odd or not */ ++ t = (double)(long)(dx / w); ++ todd = ((long)(dx / w)) & 1; ++ dekker_mul12(w, t, &c, &cc); ++ v = dx - c; ++ dx = v + (((dx - v) - c) - cc); ++ if (dx < 0.0) ++ { ++ todd = !todd; ++ dx += w; ++ } ++ ++ /* At this point, dx lies in the range [0,dy) */ ++#if !defined(COMPILING_FMOD) ++ /* For the fmod function, we're done apart from setting ++ the correct sign. */ ++ /* For the remainder function, we need to adjust dx ++ so that it lies in the range (-y/2, y/2] by carefully ++ subtracting w (== dy == y) if necessary. The rigmarole ++ with todd is to get the correct sign of the result ++ when x/y lies exactly half way between two integers, ++ when we need to choose the even integer. */ ++ if (ay < 0x7fd0000000000000) ++ { ++ if (dx + dx > w || (todd && (dx + dx == w))) ++ dx -= w; ++ } ++ else if (dx > 0.5 * w || (todd && (dx == 0.5 * w))) ++ dx -= w; ++ ++#endif ++ ++ /* **** N.B. for some reason this breaks the 32 bit version ++ of remainder when compiling with optimization. */ ++ /* Restore the entry status flags */ ++ set_fpsw_inline(sw); ++ ++ /* Set the result sign according to input argument x */ ++ return x < 0.0? -dx : dx; ++ ++} ++ ++#if defined(COMPILING_FMOD) ++weak_alias (__fmod, fmod) ++weak_alias (__fmod, __ieee754_fmod) ++#else ++weak_alias (__remainder, remainder) ++weak_alias (__remainder, __ieee754_remainder) ++#endif +diff -urpN libc/sysdeps/x86_64/fpu/w_remainderf.c libc-amd/sysdeps/x86_64/fpu/w_remainderf.c +--- libc/sysdeps/x86_64/fpu/w_remainderf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_remainderf.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,188 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_NAN_WITH_FLAGS ++#define USE_SCALEDOUBLE_1 ++#define USE_GET_FPSW_INLINE ++#define USE_SET_FPSW_INLINE ++#include "libm_inlines_amd.h" ++#undef USE_NAN_WITH_FLAGS ++#undef USE_SCALEDOUBLE_1 ++#undef USE_GET_FPSW_INLINE ++#undef USE_SET_FPSW_INLINE ++ ++#if defined(COMPILING_FMOD) ++float __fmodf(float x, float y) ++#else ++float __remainderf(float x, float y) ++#endif ++{ ++ double dx, dy, scale, w, t; ++ int i, ntimes, xexp, yexp; ++ unsigned long ux, uy, ax, ay; ++ ++ unsigned int sw; ++ ++ dx = x; ++ dy = y; ++ ++ GET_BITS_DP64(dx, ux); ++ GET_BITS_DP64(dy, uy); ++ ax = ux & ~SIGNBIT_DP64; ++ ay = uy & ~SIGNBIT_DP64; ++ xexp = ((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ yexp = ((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64); ++ ++ if (xexp < 1 || xexp > BIASEDEMAX_DP64 || ++ yexp < 1 || yexp > BIASEDEMAX_DP64) ++ { ++ /* x or y is zero, NaN or infinity (neither x nor y can be ++ denormalized because we promoted from float to double) */ ++ if (xexp > BIASEDEMAX_DP64) ++ { ++ /* x is NaN or infinity */ ++ if (ux & MANTBITS_DP64) ++ /* x is NaN */ ++ return dx + dx; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* x is infinity; result is NaN */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ else if (yexp > BIASEDEMAX_DP64) ++ { ++ /* y is NaN or infinity */ ++ if (uy & MANTBITS_DP64) ++ /* y is NaN */ ++ return dy + dy; /* Raise invalid if it is a signalling NaN */ ++ else ++ /* y is infinity; result is x */ ++ return dx; ++ } ++ else if (xexp < 1) ++ { ++ /* x must be zero (cannot be denormalized) */ ++ if (yexp < 1) ++ /* y must be zero (cannot be denormalized) */ ++ return nan_with_flags(AMD_F_INVALID); ++ else ++ return dx; ++ } ++ else ++ /* y must be zero */ ++ return nan_with_flags(AMD_F_INVALID); ++ } ++ else if (ax == ay) ++ { ++ /* abs(x) == abs(y); return zero with the sign of x */ ++ PUT_BITS_DP64(ux & SIGNBIT_DP64, dx); ++ return dx; ++ } ++ ++ /* Set dx = abs(x), dy = abs(y) */ ++ PUT_BITS_DP64(ax, dx); ++ PUT_BITS_DP64(ay, dy); ++ ++ if (ax < ay) ++ { ++ /* abs(x) < abs(y) */ ++#if !defined(COMPILING_FMOD) ++ if (dx > 0.5*dy) ++ dx -= dy; ++#endif ++ return x < 0.0? -dx : dx; ++ } ++ ++ /* Save the current floating-point status word. We need ++ to do this because the remainder function is always ++ exact for finite arguments, but our algorithm causes ++ the inexact flag to be raised. We therefore need to ++ restore the entry status before exiting. */ ++ sw = get_fpsw_inline(); ++ ++ /* Set ntimes to the number of times we need to do a ++ partial remainder. If the exponent of x is an exact multiple ++ of 24 larger than the exponent of y, and the mantissa of x is ++ less than the mantissa of y, ntimes will be one too large ++ but it doesn't matter - it just means that we'll go round ++ the loop below one extra time. */ ++ if (xexp <= yexp) ++ { ++ ntimes = 0; ++ w = dy; ++ scale = 1.0; ++ } ++ else ++ { ++ ntimes = (xexp - yexp) / 24; ++ ++ /* Set w = y * 2^(24*ntimes) */ ++ PUT_BITS_DP64((unsigned long)(ntimes * 24 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, ++ scale); ++ w = scale * dy; ++ /* Set scale = 2^(-24) */ ++ PUT_BITS_DP64((unsigned long)(-24 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64, ++ scale); ++ } ++ ++ /* Each time round the loop we compute a partial remainder. ++ This is done by subtracting a large multiple of w ++ from x each time, where w is a scaled up version of y. ++ The subtraction can be performed exactly when performed ++ in double precision, and the result at each stage can ++ fit exactly in a single precision number. */ ++ for (i = 0; i < ntimes; i++) ++ { ++ /* t is the integer multiple of w that we will subtract. ++ We use a truncated value for t. */ ++ t = (double)((int)(dx / w)); ++ dx -= w * t; ++ /* Scale w down by 2^(-24) for the next iteration */ ++ w *= scale; ++ } ++ ++ /* One more time */ ++#if defined(COMPILING_FMOD) ++ t = (double)((int)(dx / w)); ++ dx -= w * t; ++#else ++ { ++ unsigned int todd; ++ /* Variable todd says whether the integer t is odd or not */ ++ t = (double)((int)(dx / w)); ++ todd = ((int)(dx / w)) & 1; ++ dx -= w * t; ++ ++ /* At this point, dx lies in the range [0,dy) */ ++ /* For the remainder function, we need to adjust dx ++ so that it lies in the range (-y/2, y/2] by carefully ++ subtracting w (== dy == y) if necessary. */ ++ if (dx > 0.5 * w || ((dx == 0.5 * w) && todd)) ++ dx -= w; ++ } ++#endif ++ ++ /* **** N.B. for some reason this breaks the 32 bit version ++ of remainder when compiling with optimization. */ ++ /* Restore the entry status flags */ ++ set_fpsw_inline(sw); ++ ++ /* Set the result sign according to input argument x */ ++ return x < 0.0? -dx : dx; ++ ++} ++ ++#if defined(COMPILING_FMOD) ++weak_alias (__fmodf, fmodf) ++weak_alias (__fmodf, __ieee754_fmodf) ++#else ++weak_alias (__remainderf, remainderf) ++weak_alias (__remainderf, __ieee754_remainderf) ++#endif +diff -urpN libc/sysdeps/x86_64/fpu/w_remainder_piby2.c libc-amd/sysdeps/x86_64/fpu/w_remainder_piby2.c +--- libc/sysdeps/x86_64/fpu/w_remainder_piby2.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_remainder_piby2.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,541 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++/* Define this to get debugging print statements activated */ ++#define DEBUGGING_PRINT ++#undef DEBUGGING_PRINT ++ ++ ++#ifdef DEBUGGING_PRINT ++#include <stdio.h> ++char *d2b(int d, int bitsper, int point) ++{ ++ static char buff[50]; ++ int i, j; ++ j = bitsper; ++ if (point >= 0 && point <= bitsper) ++ j++; ++ buff[j] = '\0'; ++ for (i = bitsper - 1; i >= 0; i--) ++ { ++ j--; ++ if (d % 2 == 1) ++ buff[j] = '1'; ++ else ++ buff[j] = '0'; ++ if (i == point) ++ { ++ j--; ++ buff[j] = '.'; ++ } ++ d /= 2; ++ } ++ return buff; ++} ++#endif ++ ++/* Given positive argument x, reduce it to the range [-pi/4,pi/4] using ++ extra precision, and return the result in r, rr. ++ Return value "region" tells how many lots of pi/2 were subtracted ++ from x to put it in the range [-pi/4,pi/4], mod 4. */ ++void __remainder_piby2(double x, double *r, double *rr, int *region) ++{ ++ ++ /* eleven_piby4 is the closest machine number BELOW 11*pi/4 */ ++ static const double ++ eleven_piby4 = 8.6393797973719301808159e+00; /* 0x4021475cc9eedf00 */ ++ ++ static const double ++ piby2_lead = 1.57079632679489655800e+00, /* 0x3ff921fb54442d18 */ ++ piby2_tail = 6.12323399573676480327e-17, /* 0x3c91a62633145c06 */ ++ pi_lead = 3.14159265358979311600e+00, /* 0x400921fb54442d18 */ ++ pi_tail = 1.22464679914735296065e-16, /* 0x3ca1a62633145c06 */ ++ three_piby2_lead = 4.71238898038468967400e+00, /* 0x4012d97c7f3321d2 */ ++ three_piby2_tail = 1.83697019872102919446e-16, /* 0x3caa79394c9e8a08 */ ++ two_pi_lead = 6.28318530717958623200e+00, /* 0x401921fb54442d18 */ ++ two_pi_tail = 2.44929359829470592131e-16, /* 0x3cb1a62633145c06 */ ++ five_piby2_lead = 7.85398163397448278999e+00, /* 0x401f6a7a2955385e */ ++ five_piby2_tail = 3.06161699786838264816e-16; /* 0x3cb60fafbfd97308 */ ++ ++ /* Each of these threshold values is the closest machine ++ number BELOW a multiple of pi/4, i.e. they are not ++ rounded to nearest. thresh1 is 1*pi/4, thresh2 is 2*pi/4, etc. ++ This ensures that we end up in precisely the correct region. */ ++ static const double ++ thresh1 = 7.8539816339744827899949e-01, /* 0x3fe921fb54442d18 */ ++ thresh2 = 1.5707963267948965579989e+00, /* 0x3ff921fb54442d18 */ ++ thresh3 = 2.3561944901923448369984e+00, /* 0x4002d97c7f3321d2 */ ++ thresh4 = 3.1415926535897931159979e+00, /* 0x400921fb54442d18 */ ++ thresh5 = 3.9269908169872413949974e+00, /* 0x400f6a7a2955385e */ ++ thresh6 = 4.7123889803846896739969e+00, /* 0x4012d97c7f3321d2 */ ++ thresh7 = 5.4977871437821379529964e+00, /* 0x4015fdbbe9bba775 */ ++ thresh8 = 6.2831853071795862319959e+00, /* 0x401921fb54442d18 */ ++ thresh9 = 7.0685834705770345109954e+00, /* 0x401c463abeccb2bb */ ++ thresh10 = 7.8539816339744827899949e+00; /* 0x401f6a7a2955385e */ ++ ++ static const double ++ twobypi = 6.36619772367581271411E-01, /* 0x3FE45F306DC9C882 */ ++ twobypi_part1 = 6.36619761586189270020e-01, /* 0x3fe45f3068000000 */ ++ twobypi_part2 = 1.07813920013910546913e-08, /* 0x3e47272208000000 */ ++ twobypi_part3 = 7.16649491121506946045e-17, /* 0x3c94a7f09d5f47d6 */ ++ piby2_part1 = 1.57079631090164184570e+00, /* 0x3ff921fb50000000 */ ++ piby2_part2 = 1.58932547122958567343e-08, /* 0x3e5110b460000000 */ ++ piby2_part3 = 6.12323399573676480327e-17; /* 0x3c91a62633145c06 */ ++ ++ static const double cancellationThresh = 1.0e-12; ++ int done = 0; ++ ++ /* For small values of x, up to 11*pi/4, we do quad precision ++ subtraction of the relevant multiple of pi/2 */ ++ if (x <= eleven_piby4) ++ { ++ double s, t, ctest; ++ if (x <= thresh1) /* x < pi/4 */ ++ { ++ /* Quick return if x is already less than pi/4 */ ++ *r = x; ++ *rr = 0.0; ++ *region = 0; ++ return; ++ } ++ else if (x <= thresh2) /* x < 2*pi/4 */ ++ { ++ t = x - piby2_lead; ++ s = ((-piby2_lead - t) + x) - piby2_tail; ++ *region = 1; ++ } ++ else if (x <= thresh3) /* x < 3*pi/4 */ ++ { ++ t = x - piby2_lead; ++ s = ((x - t) - piby2_lead) - piby2_tail; ++ *region = 1; ++ } ++ else if (x <= thresh4) /* x < 4*pi/4 */ ++ { ++ t = x - pi_lead; ++ s = ((-pi_lead - t) + x) - pi_tail; ++ *region = 2; ++ } ++ else if (x <= thresh5) /* x < 5*pi/4 */ ++ { ++ t = x - pi_lead; ++ s = ((x - t) - pi_lead) - pi_tail; ++ *region = 2; ++ } ++ else if (x <= thresh6) /* x < 6*pi/4 */ ++ { ++ t = x - three_piby2_lead; ++ s = ((-three_piby2_lead - t) + x) - three_piby2_tail; ++ *region = 3; ++ } ++ else if (x <= thresh7) /* x < 7*pi/4 */ ++ { ++ t = x - three_piby2_lead; ++ s = ((x - t) - three_piby2_lead) - three_piby2_tail; ++ *region = 3; ++ } ++ else if (x <= thresh8) /* x < 8*pi/4 */ ++ { ++ t = x - two_pi_lead; ++ s = ((-two_pi_lead - t) + x) - two_pi_tail; ++ *region = 0; ++ } ++ else if (x <= thresh9) /* x < 9*pi/4 */ ++ { ++ t = x - two_pi_lead; ++ s = ((x - t) - two_pi_lead) - two_pi_tail; ++ *region = 0; ++ } ++ else if (x <= thresh10) /* x < 10*pi/4 */ ++ { ++ t = x - five_piby2_lead; ++ s = ((-five_piby2_lead - t) + x) - five_piby2_tail; ++ *region = 1; ++ } ++ else /* x < 11*pi/4 */ ++ { ++ t = x - five_piby2_lead; ++ s = ((x - t) - five_piby2_lead) - five_piby2_tail; ++ *region = 1; ++ } ++ ++ *r = t + s; ++ *rr = (t - *r) + s; ++ ++ /* Check for massive cancellation which may happen very close ++ to multiples of pi/2 */ ++ if (*r < 0.0) ++ ctest = -(*r); ++ else ++ ctest = *r; ++#ifdef DEBUGGING_PRINT ++ printf("Cancellation threshold test = (%g > %g)\n", ++ ctest, cancellationThresh); ++#endif ++ ++ /* Check if cancellation error was not too large */ ++ if (ctest > cancellationThresh) ++ done = 1; ++ /* Otherwise fall through to the expensive method */ ++ } ++ else if (x <= 1.0e5) ++ { ++ /* This range reduction is accurate enough for x up to ++ approximately 2**(20) except near multiples of pi/2 */ ++ ++ /* We perform quad precision arithmetic to find the ++ nearest multiple of pi/2 to x */ ++ ++ int reg, it; ++ double hx, tx, z, zz, w, ww, dreg, s, t, c, cc, ctest; ++ ++ /* Split x into head and tail, hx and tx */ ++ unsigned long u; ++ GET_BITS_DP64(x, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hx); ++ tx = x - hx; ++ ++ /* Multiply x by 2/pi in extra precision, result in (z, zz) */ ++ c = x * twobypi; ++ cc = ((((hx * twobypi_part1 - c) + hx * twobypi_part2) + ++ tx * twobypi_part1) + tx * twobypi_part2) + x * twobypi_part3; ++ z = c + cc; ++ zz = (c - z) + cc; ++ ++#ifdef DEBUGGING_PRINT ++ printf("z = %30.20e = %s\n", z, double2hex(&z)); ++ printf("zz = %30.20e = %s\n", zz, double2hex(&zz)); ++#endif ++ ++ /* Find reg, the nearest integer to (z, zz). We need to be ++ careful when (z,zz) is very near an odd multiple of 0.5. ++ The simple formula ++ reg = (int)((zz + 0.5) + z); ++ fails in that case because the double rounding may ++ lead us astray. */ ++ t = z + z; ++ it = (int)t; ++ if (it == t && it & 1) ++ { ++ /* z is an odd multiple of 0.5; we must use zz ++ to discriminate */ ++ if (zz > 0.0) ++ reg = (int)z + 1; ++ else ++ reg = (int)z; ++ } ++ else ++ reg = (int)(z + 0.5); ++ ++#ifdef DEBUGGING_PRINT ++ printf("reg = %d\n", reg); ++#endif ++ ++ /* Carefully subtract reg from (z, zz), result in (w, ww) */ ++ dreg = reg; ++ s = z - dreg; ++ if (z > dreg) ++ t = ((z - s) - dreg) + zz; ++ else ++ t = ((-dreg - s) + z) + zz; ++ w = s + t; ++ ww = (s - w) + t; ++ ++#ifdef DEBUGGING_PRINT ++ printf("w = %30.20e = %s\n", w, double2hex(&w)); ++ printf("ww = %30.20e = %s\n", ww, double2hex(&ww)); ++#endif ++ ++ /* Check for massive cancellation which may happen very close ++ to multiples of pi/2 */ ++ if (w < 0.0) ++ ctest = -w; ++ else ++ ctest = w; ++ ++ /* If cancellation is not too severe, continue with this method. ++ Otherwise we fall through to the expensive, accurate method */ ++ if (ctest > cancellationThresh) ++ { ++ /* Split w into (hx, tx) */ ++ GET_BITS_DP64(w, u); ++ u &= 0xfffffffff8000000; ++ PUT_BITS_DP64(u, hx); ++ tx = w - hx; ++ ++ /* Carefully multiply (w, ww) by pi/2 */ ++ c = piby2_lead * w; ++ cc = ((((piby2_part1 * hx - c) + piby2_part1 * tx) + ++ piby2_part2 * hx) + piby2_part2 * tx) + ++ (piby2_lead * ww + piby2_part3 * w); ++ *r = c + cc; ++ *rr = (c - *r) + cc; ++ ++ *region = reg & 3; ++ ++#ifdef DEBUGGING_PRINT ++ printf("r = %30.20e = %s\n", *r, double2hex(r)); ++ printf("rr = %30.20e = %s\n", *rr, double2hex(rr)); ++#endif ++ done = 1; ++ } ++ } ++ ++ if (!done) ++ { ++ /* This method simulates multi-precision floating-point ++ arithmetic and is accurate for all 1 <= x < infinity */ ++ const int bitsper = 10; ++ unsigned long res[500]; ++ unsigned long ux, u, carry, mask, mant, highbitsrr; ++ int first, last, i, rexp, xexp, resexp, ltb, determ; ++ double xx, t; ++ static unsigned long pibits[] = ++ { ++ 0, 0, 0, 0, 0, 0, ++ 162, 998, 54, 915, 580, 84, 671, 777, 855, 839, ++ 851, 311, 448, 877, 553, 358, 316, 270, 260, 127, ++ 593, 398, 701, 942, 965, 390, 882, 283, 570, 265, ++ 221, 184, 6, 292, 750, 642, 465, 584, 463, 903, ++ 491, 114, 786, 617, 830, 930, 35, 381, 302, 749, ++ 72, 314, 412, 448, 619, 279, 894, 260, 921, 117, ++ 569, 525, 307, 637, 156, 529, 504, 751, 505, 160, ++ 945, 1022, 151, 1023, 480, 358, 15, 956, 753, 98, ++ 858, 41, 721, 987, 310, 507, 242, 498, 777, 733, ++ 244, 399, 870, 633, 510, 651, 373, 158, 940, 506, ++ 997, 965, 947, 833, 825, 990, 165, 164, 746, 431, ++ 949, 1004, 287, 565, 464, 533, 515, 193, 111, 798 ++ }; ++ ++ GET_BITS_DP64(x, ux); ++ ++#ifdef DEBUGGING_PRINT ++ printf("On entry, x = %25.20e = %s\n", x, double2hex(&x)); ++#endif ++ ++ xexp = (int)(((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64); ++ ux = (ux & MANTBITS_DP64) | IMPBIT_DP64; ++ ++ /* Now ux is the mantissa bit pattern of x as a long integer */ ++ carry = 0; ++ mask = (1L << bitsper) - 1; ++ ++ /* Set first and last to the positions of the first ++ and last chunks of 2/pi that we need */ ++ first = xexp / bitsper; ++ resexp = xexp - first * bitsper; ++ /* 180 is the theoretical maximum number of bits (actually ++ 175 for IEEE double precision) that we need to extract ++ from the middle of 2/pi to compute the reduced argument ++ accurately enough for our purposes */ ++ last = first + 180 / bitsper; ++ ++ /* Do a long multiplication of the bits of 2/pi by the ++ integer mantissa */ ++#if 0 ++ for (i = last; i >= first; i--) ++ { ++ u = pibits[i] * ux + carry; ++ res[i - first] = u & mask; ++ carry = u >> bitsper; ++ } ++ res[last - first + 1] = 0; ++#else ++ /* Unroll the loop. This is only correct because we know ++ that bitsper is fixed as 10. */ ++ res[19] = 0; ++ u = pibits[last] * ux; ++ res[18] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-1] * ux + carry; ++ res[17] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-2] * ux + carry; ++ res[16] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-3] * ux + carry; ++ res[15] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-4] * ux + carry; ++ res[14] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-5] * ux + carry; ++ res[13] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-6] * ux + carry; ++ res[12] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-7] * ux + carry; ++ res[11] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-8] * ux + carry; ++ res[10] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-9] * ux + carry; ++ res[9] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-10] * ux + carry; ++ res[8] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-11] * ux + carry; ++ res[7] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-12] * ux + carry; ++ res[6] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-13] * ux + carry; ++ res[5] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-14] * ux + carry; ++ res[4] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-15] * ux + carry; ++ res[3] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-16] * ux + carry; ++ res[2] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-17] * ux + carry; ++ res[1] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last-18] * ux + carry; ++ res[0] = u & mask; ++#endif ++ ++#ifdef DEBUGGING_PRINT ++ printf("resexp = %d\n", resexp); ++ printf("Significant part of x * 2/pi with binary" ++ " point in correct place:\n"); ++ for (i = 0; i <= last - first; i++) ++ { ++ if (i > 0 && i % 5 == 0) ++ printf("\n "); ++ if (i == 1) ++ printf("%s ", d2b((int)res[i], bitsper, resexp)); ++ else ++ printf("%s ", d2b((int)res[i], bitsper, -1)); ++ } ++ printf("\n"); ++#endif ++ ++ /* Reconstruct the result */ ++ ltb = (int)((((res[0] << bitsper) | res[1]) ++ >> (bitsper - 1 - resexp)) & 7); ++ ++ /* determ says whether the fractional part is >= 0.5 */ ++ determ = ltb & 1; ++ ++#ifdef DEBUGGING_PRINT ++ printf("ltb = %d (last two bits before binary point" ++ " and first bit after)\n", ltb); ++ printf("determ = %d (1 means need to negate because the fractional\n" ++ " part of x * 2/pi is greater than 0.5)\n", determ); ++#endif ++ ++ i = 1; ++ if (determ) ++ { ++ /* The mantissa is >= 0.5. We want to subtract it ++ from 1.0 by negating all the bits */ ++ *region = ((ltb >> 1) + 1) & 3; ++ mant = ~(res[1]) & ((1L << (bitsper - resexp)) - 1); ++ while (mant < 0x0020000000000000) ++ { ++ i++; ++ mant = (mant << bitsper) | (~(res[i]) & mask); ++ } ++ highbitsrr = ~(res[i + 1]) << (64 - bitsper); ++ } ++ else ++ { ++ *region = (ltb >> 1); ++ mant = res[1] & ((1L << (bitsper - resexp)) - 1); ++ while (mant < 0x0020000000000000) ++ { ++ i++; ++ mant = (mant << bitsper) | res[i]; ++ } ++ highbitsrr = res[i + 1] << (64 - bitsper); ++ } ++ ++ rexp = 52 + resexp - i * bitsper; ++ ++ while (mant >= 0x0020000000000000) ++ { ++ rexp++; ++ highbitsrr = (highbitsrr >> 1) | ((mant & 1) << 63); ++ mant >>= 1; ++ } ++ ++#ifdef DEBUGGING_PRINT ++ printf("Normalised mantissa = 0x%016lx\n", mant); ++ printf("High bits of rest of mantissa = 0x%016lx\n", highbitsrr); ++ printf("Exponent to be inserted on mantissa = rexp = %d\n", rexp); ++#endif ++ ++ /* Put the result exponent rexp onto the mantissa pattern */ ++ u = ((unsigned long)rexp + EXPBIAS_DP64) << EXPSHIFTBITS_DP64; ++ ux = (mant & MANTBITS_DP64) | u; ++ if (determ) ++ /* If we negated the mantissa we negate x too */ ++ ux |= SIGNBIT_DP64; ++ PUT_BITS_DP64(ux, x); ++ ++ /* Create the bit pattern for rr */ ++ highbitsrr >>= 12; /* Note this is shifted one place too far */ ++ u = ((unsigned long)rexp + EXPBIAS_DP64 - 53) << EXPSHIFTBITS_DP64; ++ PUT_BITS_DP64(u, t); ++ u |= highbitsrr; ++ PUT_BITS_DP64(u, xx); ++ ++ /* Subtract the implicit bit we accidentally added */ ++ xx -= t; ++ /* Set the correct sign, and double to account for the ++ "one place too far" shift */ ++ if (determ) ++ xx *= -2.0; ++ else ++ xx *= 2.0; ++ ++#ifdef DEBUGGING_PRINT ++ printf("(lead part of x*2/pi) = %25.20e = %s\n", x, double2hex(&x)); ++ printf("(tail part of x*2/pi) = %25.20e = %s\n", xx, double2hex(&xx)); ++#endif ++ ++ /* (x,xx) is an extra-precise version of the fractional part of ++ x * 2 / pi. Multiply (x,xx) by pi/2 in extra precision ++ to get the reduced argument (r,rr). */ ++ { ++ double hx, tx, c, cc; ++ /* Split x into hx (head) and tx (tail) */ ++ GET_BITS_DP64(x, ux); ++ ux &= 0xfffffffff8000000; ++ PUT_BITS_DP64(ux, hx); ++ tx = x - hx; ++ ++ c = piby2_lead * x; ++ cc = ((((piby2_part1 * hx - c) + piby2_part1 * tx) + ++ piby2_part2 * hx) + piby2_part2 * tx) + ++ (piby2_lead * xx + piby2_part3 * x); ++ *r = c + cc; ++ *rr = (c - *r) + cc; ++ } ++ ++#ifdef DEBUGGING_PRINT ++ printf(" (r,rr) = lead and tail parts of frac(x*2/pi) * pi/2:\n"); ++ printf(" r = %25.20e = %s\n", *r, double2hex(r)); ++ printf("rr = %25.20e = %s\n", *rr, double2hex(rr)); ++ printf("region = (number of pi/2 subtracted from x) mod 4 = %d\n", ++ *region); ++#endif ++ } ++} +diff -urpN libc/sysdeps/x86_64/fpu/w_remainder_piby2f.c libc-amd/sysdeps/x86_64/fpu/w_remainder_piby2f.c +--- libc/sysdeps/x86_64/fpu/w_remainder_piby2f.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_remainder_piby2f.c 2006-03-22 00:53:49.000000000 +0100 +@@ -0,0 +1,386 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++/* Define this to get debugging print statements activated */ ++#define DEBUGGING_PRINT ++#undef DEBUGGING_PRINT ++ ++ ++#ifdef DEBUGGING_PRINT ++#include <stdio.h> ++char *d2b(long d, int bitsper, int point) ++{ ++ static char buff[200]; ++ int i, j; ++ j = bitsper; ++ if (point >= 0 && point <= bitsper) ++ j++; ++ buff[j] = '\0'; ++ for (i = bitsper - 1; i >= 0; i--) ++ { ++ j--; ++ if (d % 2 == 1) ++ buff[j] = '1'; ++ else ++ buff[j] = '0'; ++ if (i == point) ++ { ++ j--; ++ buff[j] = '.'; ++ } ++ d /= 2; ++ } ++ return buff; ++} ++#endif ++ ++/* Given positive argument x, reduce it to the range [-pi/4,pi/4] using ++ extra precision, and return the result in r. ++ Return value "region" tells how many lots of pi/2 were subtracted ++ from x to put it in the range [-pi/4,pi/4], mod 4. */ ++void __remainder_piby2f(float x, double *r, int *region) ++{ ++ ++ /* eleven_piby4 is the closest machine number BELOW 11*pi/4 */ ++ static const double ++ eleven_piby4 = 8.6393797973719301808159e+00; /* 0x4021475cc9eedf00 */ ++ ++ static const double ++ piby2 = 1.57079632679489655800e+00, /* 0x3ff921fb54442d18 */ ++ twobypi = 6.36619772367581382433e-01, /* 0x3fe45f306dc9c883 */ ++ pi = 3.14159265358979311600e+00, /* 0x400921fb54442d18 */ ++ three_piby2 = 4.71238898038468967400e+00, /* 0x4012d97c7f3321d2 */ ++ two_pi = 6.28318530717958623200e+00, /* 0x401921fb54442d18 */ ++ five_piby2 = 7.85398163397448278999e+00; /* 0x401f6a7a2955385e */ ++ ++ /* Each of these threshold values is the closest machine ++ number BELOW a multiple of pi/4, i.e. they are not ++ rounded to nearest. thresh1 is 1*pi/4, thresh3 is 3*pi/4, etc. ++ This ensures that we end up in precisely the correct region. */ ++ static const double ++ thresh1 = 7.8539816339744827899949e-01, /* 0x3fe921fb54442d18 */ ++ thresh3 = 2.3561944901923448369984e+00, /* 0x4002d97c7f3321d2 */ ++ thresh5 = 3.9269908169872413949974e+00, /* 0x400f6a7a2955385e */ ++ thresh7 = 5.4977871437821379529964e+00, /* 0x4015fdbbe9bba775 */ ++ thresh9 = 7.0685834705770345109954e+00; /* 0x401c463abeccb2bb */ ++ ++ static const double cancellationThresh = 1.0e-5; ++ int done = 0; ++ double dx; ++ ++ dx = x; ++ ++ /* For small values of x, up to 11*pi/4, we do double precision ++ subtraction of the relevant multiple of pi/2 */ ++ if (dx <= eleven_piby4) /* x <= 11*pi/4 */ ++ { ++ double t, ctest; ++ ++ if (dx <= thresh5) /* x < 5*pi/4 */ ++ { ++ if (dx <= thresh1) /* x < pi/4 */ ++ { ++ /* Quick return if x is already less than pi/4 */ ++ *r = dx; ++ *region = 0; ++ return; ++ } ++ else if (dx <= thresh3) /* x < 3*pi/4 */ ++ { ++ t = dx - piby2; ++ *region = 1; ++ } ++ else /* x < 5*pi/4 */ ++ { ++ t = dx - pi; ++ *region = 2; ++ } ++ } ++ else ++ { ++ if (dx <= thresh7) /* x < 7*pi/4 */ ++ { ++ t = dx - three_piby2; ++ *region = 3; ++ } ++ else if (dx <= thresh9) /* x < 9*pi/4 */ ++ { ++ t = dx - two_pi; ++ *region = 0; ++ } ++ else /* x < 11*pi/4 */ ++ { ++ t = dx - five_piby2; ++ *region = 1; ++ } ++ } ++ ++ /* Check for massive cancellation which may happen very close ++ to multiples of pi/2 */ ++ if (t < 0.0) ++ ctest = -t; ++ else ++ ctest = t; ++#ifdef DEBUGGING_PRINT ++ printf("Cancellation threshold test = (%g > %g)\n", ++ ctest, cancellationThresh); ++#endif ++ ++ /* Check if cancellation error was not too large */ ++ if (ctest > cancellationThresh) ++ { ++ *r = t; ++ done = 1; ++ } ++ /* Otherwise fall through to the expensive method */ ++ } ++ else if (dx <= 1.0e6) ++ { ++ /* This range reduction is accurate enough for x up to ++ approximately 2**(20) except near multiples of pi/2 */ ++ ++ /* We perform double precision arithmetic to find the ++ nearest multiple of pi/2 to x */ ++ int reg; ++ double z, w, c, ctest; ++ ++ /* Multiply x by 2/pi in double precision, result in z */ ++ z = dx * twobypi; ++ ++#ifdef DEBUGGING_PRINT ++ printf("z = %30.20e = %s\n", z, double2hex(&z)); ++#endif ++ ++ /* Find reg, the nearest integer to z */ ++ reg = (int)(z + 0.5); ++ ++#ifdef DEBUGGING_PRINT ++ printf("reg = %d\n", reg); ++#endif ++ ++ /* Subtract reg from z, result in w */ ++ w = z - reg; ++ ++#ifdef DEBUGGING_PRINT ++ printf("w = %30.20e = %s\n", w, double2hex(&w)); ++#endif ++ ++ /* Check for massive cancellation which may happen very close ++ to multiples of pi/2 */ ++ if (w < 0.0) ++ ctest = -w; ++ else ++ ctest = w; ++ ++ /* If cancellation is not too severe, continue with this method. ++ Otherwise we fall through to the expensive, accurate method */ ++ if (ctest > cancellationThresh) ++ { ++ /* Multiply w by pi/2 */ ++ c = w * piby2; ++ *r = c; ++ *region = reg & 3; ++ ++#ifdef DEBUGGING_PRINT ++ printf("r = %30.20e = %s\n", *r, double2hex(r)); ++#endif ++ done = 1; ++ } ++ } ++ ++ if (!done) ++ { ++ /* This method simulates multi-precision floating-point ++ arithmetic and is accurate for all 1 <= x < infinity */ ++#if 0 ++ const int bitsper = 36; ++#else ++#define bitsper 36 ++#endif ++ unsigned long res[10]; ++ unsigned long u, carry, mask, mant, nextbits; ++ unsigned long ux; ++ int first, last, i, rexp, xexp, resexp, ltb, determ, bc; ++ static const double ++ piby2 = 1.57079632679489655800e+00; /* 0x3ff921fb54442d18 */ ++ static unsigned long pibits[] = ++ { ++ 0L, ++ 5215L, 13000023176L, 11362338026L, 67174558139L, ++ 34819822259L, 10612056195L, 67816420731L, 57840157550L, ++ 19558516809L, 50025467026L, 25186875954L, 18152700886L ++ }; ++ ++#ifdef DEBUGGING_PRINT ++ printf("On entry, x = %25.20e = %s\n", dx, double2hex(&dx)); ++#endif ++ ++ ++ GET_BITS_DP64(dx, ux); ++ ++ xexp = (int)(((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64); ++ ux = ((ux & MANTBITS_DP64) | IMPBIT_DP64) >> 29; ++ ++#ifdef DEBUGGING_PRINT ++ printf("ux = %s\n", d2b(ux, 64, -1)); ++#endif ++ ++ /* Now ux is the mantissa bit pattern of x as a long integer */ ++ mask = (1L << bitsper) - 1; ++ ++ /* Set first and last to the positions of the first ++ and last chunks of 2/pi that we need */ ++ first = xexp / bitsper; ++ resexp = xexp - first * bitsper; ++ /* 120 is the theoretical maximum number of bits (actually ++ 115 for IEEE single precision) that we need to extract ++ from the middle of 2/pi to compute the reduced argument ++ accurately enough for our purposes */ ++ last = first + 120 / bitsper; ++ ++#ifdef DEBUGGING_PRINT ++ printf("first = %d, last = %d\n", first, last); ++#endif ++ ++ /* Do a long multiplication of the bits of 2/pi by the ++ integer mantissa */ ++#if 0 ++ for (i = last; i >= first; i--) ++ { ++ u = pibits[i] * ux + carry; ++ res[i - first] = u & mask; ++ carry = u >> bitsper; ++ } ++ res[last - first + 1] = 0; ++#else ++ /* Unroll the loop. This is only correct because we know ++ that bitsper is fixed as 36. */ ++ res[4] = 0; ++ u = pibits[last] * ux; ++ res[3] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last - 1] * ux + carry; ++ res[2] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[last - 2] * ux + carry; ++ res[1] = u & mask; ++ carry = u >> bitsper; ++ u = pibits[first] * ux + carry; ++ res[0] = u & mask; ++#endif ++ ++#ifdef DEBUGGING_PRINT ++ printf("resexp = %d\n", resexp); ++ printf("Significant part of x * 2/pi with binary" ++ " point in correct place:\n"); ++ for (i = 0; i <= last - first; i++) ++ { ++ if (i > 0 && i % 5 == 0) ++ printf("\n "); ++ if (i == 1) ++ printf("%s ", d2b(res[i], bitsper, resexp)); ++ else ++ printf("%s ", d2b(res[i], bitsper, -1)); ++ } ++ printf("\n"); ++#endif ++ ++ /* Reconstruct the result */ ++ ltb = (int)((((res[0] << bitsper) | res[1]) ++ >> (bitsper - 1 - resexp)) & 7); ++ ++ /* determ says whether the fractional part is >= 0.5 */ ++ determ = ltb & 1; ++ ++#ifdef DEBUGGING_PRINT ++ printf("ltb = %d (last two bits before binary point" ++ " and first bit after)\n", ltb); ++ printf("determ = %d (1 means need to negate because the fractional\n" ++ " part of x * 2/pi is greater than 0.5)\n", determ); ++#endif ++ ++ i = 1; ++ if (determ) ++ { ++ /* The mantissa is >= 0.5. We want to subtract it ++ from 1.0 by negating all the bits */ ++ *region = ((ltb >> 1) + 1) & 3; ++ mant = ~(res[1]) & ((1L << (bitsper - resexp)) - 1); ++ while (mant < 0x0000000000010000) ++ { ++ i++; ++ mant = (mant << bitsper) | (~(res[i]) & mask); ++ } ++ nextbits = (~(res[i+1]) & mask); ++ } ++ else ++ { ++ *region = (ltb >> 1); ++ mant = res[1] & ((1L << (bitsper - resexp)) - 1); ++ while (mant < 0x0000000000010000) ++ { ++ i++; ++ mant = (mant << bitsper) | res[i]; ++ } ++ nextbits = res[i+1]; ++ } ++ ++#ifdef DEBUGGING_PRINT ++ printf("First bits of mant = %s\n", d2b(mant, bitsper, -1)); ++#endif ++ ++ /* Normalize the mantissa. The shift value 6 here, determined by ++ trial and error, seems to give optimal speed. */ ++ bc = 0; ++ while (mant < 0x0000400000000000) ++ { ++ bc += 6; ++ mant <<= 6; ++ } ++ while (mant < 0x0010000000000000) ++ { ++ bc++; ++ mant <<= 1; ++ } ++ mant |= nextbits >> (bitsper - bc); ++ ++ rexp = 52 + resexp - bc - i * bitsper; ++ ++#ifdef DEBUGGING_PRINT ++ printf("Normalised mantissa = 0x%016lx\n", mant); ++ printf("Exponent to be inserted on mantissa = rexp = %d\n", rexp); ++#endif ++ ++ /* Put the result exponent rexp onto the mantissa pattern */ ++ u = ((unsigned long)rexp + EXPBIAS_DP64) << EXPSHIFTBITS_DP64; ++ ux = (mant & MANTBITS_DP64) | u; ++ if (determ) ++ /* If we negated the mantissa we negate x too */ ++ ux |= SIGNBIT_DP64; ++ PUT_BITS_DP64(ux, dx); ++ ++#ifdef DEBUGGING_PRINT ++ printf("(x*2/pi) = %25.20e = %s\n", dx, double2hex(&dx)); ++#endif ++ ++ /* x is a double precision version of the fractional part of ++ x * 2 / pi. Multiply x by pi/2 in double precision ++ to get the reduced argument r. */ ++ *r = dx * piby2; ++ ++#ifdef DEBUGGING_PRINT ++ printf(" r = frac(x*2/pi) * pi/2:\n"); ++ printf(" r = %25.20e = %s\n", *r, double2hex(r)); ++ printf("region = (number of pi/2 subtracted from x) mod 4 = %d\n", ++ *region); ++#endif ++ } ++} +diff -urpN libc/sysdeps/x86_64/fpu/w_sinh.c libc-amd/sysdeps/x86_64/fpu/w_sinh.c +--- libc/sysdeps/x86_64/fpu/w_sinh.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_sinh.c 2006-03-22 02:32:13.000000000 +0100 +@@ -0,0 +1,336 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_INFINITY_WITH_FLAGS ++#define USE_VAL_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_INFINITY_WITH_FLAGS ++#undef USE_VAL_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline double retval_errno_erange(double x, int xneg) ++{ ++ struct exception exc; ++ exc.arg1 = x; ++ exc.arg2 = x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"sinh"; ++ if (_LIB_VERSION == _SVID_) ++ { ++ if (xneg) ++ exc.retval = -HUGE; ++ else ++ exc.retval = HUGE; ++ } ++ else ++ { ++ if (xneg) ++ exc.retval = -infinity_with_flags(AMD_F_OVERFLOW); ++ else ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW); ++ } ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++double __sinh(double x) ++{ ++ /* ++ After dealing with special cases the computation is split into ++ regions as follows: ++ ++ abs(x) >= max_sinh_arg: ++ sinh(x) = sign(x)*Inf ++ ++ abs(x) >= small_threshold: ++ sinh(x) = sign(x)*exp(abs(x))/2 computed using the ++ splitexp and scaleDouble functions as for exp_amd(). ++ ++ abs(x) < small_threshold: ++ compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) ++ sinh(x) is then sign(x)*z. */ ++ ++ static const double ++ max_sinh_arg = 7.10475860073943977113e+02, /* 0x408633ce8fb9f87e */ ++ thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ ++ log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ ++ log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ ++ small_threshold = 8*BASEDIGITS_DP64*0.30102999566398119521373889; ++ /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ ++ ++ /* Lead and tail tabulated values of sinh(i) and cosh(i) ++ for i = 0,...,36. The lead part has 26 leading bits. */ ++ ++ static const double sinh_lead[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.17520117759704589844e+00, /* 0x3ff2cd9fc0000000 */ ++ 3.62686038017272949219e+00, /* 0x400d03cf60000000 */ ++ 1.00178747177124023438e+01, /* 0x40240926e0000000 */ ++ 2.72899169921875000000e+01, /* 0x403b4a3800000000 */ ++ 7.42032089233398437500e+01, /* 0x40528d0160000000 */ ++ 2.01713153839111328125e+02, /* 0x406936d228000000 */ ++ 5.48316116333007812500e+02, /* 0x4081228768000000 */ ++ 1.49047882080078125000e+03, /* 0x409749ea50000000 */ ++ 4.05154187011718750000e+03, /* 0x40afa71570000000 */ ++ 1.10132326660156250000e+04, /* 0x40c5829dc8000000 */ ++ 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ ++ 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ ++ 2.21206695312500000000e+05, /* 0x410b00b590000000 */ ++ 6.01302140625000000000e+05, /* 0x412259ac48000000 */ ++ 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ ++ 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ ++ 1.20774762500000000000e+07, /* 0x4167093488000000 */ ++ 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ ++ 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ ++ 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ ++ 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ ++ 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ ++ 4.87240166400000000000e+09, /* 0x41f226af30000000 */ ++ 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ ++ 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ ++ 9.78648043520000000000e+10, /* 0x4236c93268000000 */ ++ 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ ++ 7.23128516608000000000e+11, /* 0x42650bba30000000 */ ++ 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ ++ 5.34323724288000000000e+12, /* 0x4293704708000000 */ ++ 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ ++ 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ ++ 1.07321789251584000000e+14, /* 0x42d866f348000000 */ ++ 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ ++ 7.93006722514944000000e+14, /* 0x430689e220000000 */ ++ 2.15561576592179200000e+15}; /* 0x431ea215a0000000 */ ++ ++ static const double sinh_tail[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.60467555584448807892e-08, /* 0x3e513ae6096a0092 */ ++ 2.76742892754807136947e-08, /* 0x3e5db70cfb79a640 */ ++ 2.09697499555224576530e-07, /* 0x3e8c2526b66dc067 */ ++ 2.04940252448908240062e-07, /* 0x3e8b81b18647f380 */ ++ 1.65444891522700935932e-06, /* 0x3ebbc1cdd1e1eb08 */ ++ 3.53116789999998198721e-06, /* 0x3ecd9f201534fb09 */ ++ 6.94023870987375490695e-06, /* 0x3edd1c064a4e9954 */ ++ 4.98876893611587449271e-06, /* 0x3ed4eca65d06ea74 */ ++ 3.19656024605152215752e-05, /* 0x3f00c259bcc0ecc5 */ ++ 2.08687768377236501204e-04, /* 0x3f2b5a6647cf9016 */ ++ 4.84668088325403796299e-05, /* 0x3f09691adefb0870 */ ++ 1.17517985422733832468e-03, /* 0x3f53410fc29cde38 */ ++ 6.90830086959560562415e-04, /* 0x3f46a31a50b6fb3c */ ++ 1.45697262451506548420e-03, /* 0x3f57defc71805c40 */ ++ 2.99859023684906737806e-02, /* 0x3f9eb49fd80e0bab */ ++ 1.02538800507941396667e-02, /* 0x3f84fffc7bcd5920 */ ++ 1.26787628407699110022e-01, /* 0x3fc03a93b6c63435 */ ++ 6.86652479544033744752e-02, /* 0x3fb1940bb255fd1c */ ++ 4.81593627621056619148e-01, /* 0x3fded26e14260b50 */ ++ 1.70489513795397629181e+00, /* 0x3ffb47401fc9f2a2 */ ++ 1.12416073482258713767e+01, /* 0x40267bb3f55634f1 */ ++ 7.06579578070110514432e+00, /* 0x401c435ff8194ddc */ ++ 5.91244512999659974639e+01, /* 0x404d8fee052ba63a */ ++ 1.68921736147050694399e+02, /* 0x40651d7edccde3f6 */ ++ 2.60692936262073658327e+02, /* 0x40704b1644557d1a */ ++ 3.62419382134885609048e+02, /* 0x4076a6b5ca0a9dc4 */ ++ 4.07689930834187271103e+03, /* 0x40afd9cc72249aba */ ++ 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ ++ 2.53720210371943067003e+04, /* 0x40d8c70158ac6363 */ ++ 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ ++ 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ ++ 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ ++ 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ ++ 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ ++ 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ ++ 7.63580561355670914054e+06}; /* 0x415d20d76744835c */ ++ ++ static const double cosh_lead[ 37] = { ++ 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ ++ 1.54308062791824340820e+00, /* 0x3ff8b07550000000 */ ++ 3.76219564676284790039e+00, /* 0x400e18fa08000000 */ ++ 1.00676617622375488281e+01, /* 0x402422a490000000 */ ++ 2.73082327842712402344e+01, /* 0x403b4ee858000000 */ ++ 7.42099475860595703125e+01, /* 0x40528d6fc8000000 */ ++ 2.01715633392333984375e+02, /* 0x406936e678000000 */ ++ 5.48317031860351562500e+02, /* 0x4081228948000000 */ ++ 1.49047915649414062500e+03, /* 0x409749eaa8000000 */ ++ 4.05154199218750000000e+03, /* 0x40afa71580000000 */ ++ 1.10132329101562500000e+04, /* 0x40c5829dd0000000 */ ++ 2.99370708007812500000e+04, /* 0x40dd3c4488000000 */ ++ 8.13773945312500000000e+04, /* 0x40f3de1650000000 */ ++ 2.21206695312500000000e+05, /* 0x410b00b590000000 */ ++ 6.01302140625000000000e+05, /* 0x412259ac48000000 */ ++ 1.63450865625000000000e+06, /* 0x4138f0cca8000000 */ ++ 4.44305525000000000000e+06, /* 0x4150f2ebd0000000 */ ++ 1.20774762500000000000e+07, /* 0x4167093488000000 */ ++ 3.28299845000000000000e+07, /* 0x417f4f2208000000 */ ++ 8.92411500000000000000e+07, /* 0x419546d8f8000000 */ ++ 2.42582596000000000000e+08, /* 0x41aceb0888000000 */ ++ 6.59407856000000000000e+08, /* 0x41c3a6e1f8000000 */ ++ 1.79245641600000000000e+09, /* 0x41dab5adb8000000 */ ++ 4.87240166400000000000e+09, /* 0x41f226af30000000 */ ++ 1.32445608960000000000e+10, /* 0x4208ab7fb0000000 */ ++ 3.60024494080000000000e+10, /* 0x4220c3d390000000 */ ++ 9.78648043520000000000e+10, /* 0x4236c93268000000 */ ++ 2.66024116224000000000e+11, /* 0x424ef822f0000000 */ ++ 7.23128516608000000000e+11, /* 0x42650bba30000000 */ ++ 1.96566712320000000000e+12, /* 0x427c9aae40000000 */ ++ 5.34323724288000000000e+12, /* 0x4293704708000000 */ ++ 1.45244246507520000000e+13, /* 0x42aa6b7658000000 */ ++ 3.94814795284480000000e+13, /* 0x42c1f43fc8000000 */ ++ 1.07321789251584000000e+14, /* 0x42d866f348000000 */ ++ 2.91730863685632000000e+14, /* 0x42f0953e28000000 */ ++ 7.93006722514944000000e+14, /* 0x430689e220000000 */ ++ 2.15561576592179200000e+15}; /* 0x431ea215a0000000 */ ++ ++ static const double cosh_tail[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 6.89700037027478056904e-09, /* 0x3e3d9f5504c2bd28 */ ++ 4.43207835591715833630e-08, /* 0x3e67cb66f0a4c9fd */ ++ 2.33540217013828929694e-07, /* 0x3e8f58617928e588 */ ++ 5.17452463948269748331e-08, /* 0x3e6bc7d000c38d48 */ ++ 9.38728274131605919153e-07, /* 0x3eaf7f9d4e329998 */ ++ 2.73012191010840495544e-06, /* 0x3ec6e6e464885269 */ ++ 3.29486051438996307950e-06, /* 0x3ecba3a8b946c154 */ ++ 4.75803746362771416375e-06, /* 0x3ed3f4e76110d5a4 */ ++ 3.33050940471947692369e-05, /* 0x3f017622515a3e2b */ ++ 9.94707313972136215365e-06, /* 0x3ee4dc4b528af3d0 */ ++ 6.51685096227860253398e-05, /* 0x3f11156278615e10 */ ++ 1.18132406658066663359e-03, /* 0x3f535ad50ed821f5 */ ++ 6.93090416366541877541e-04, /* 0x3f46b61055f2935c */ ++ 1.45780415323416845386e-03, /* 0x3f57e2794a601240 */ ++ 2.99862082708111758744e-02, /* 0x3f9eb4b45f6aadd3 */ ++ 1.02539925859688602072e-02, /* 0x3f85000b967b3698 */ ++ 1.26787669807076286421e-01, /* 0x3fc03a940fadc092 */ ++ 6.86652631843830962843e-02, /* 0x3fb1940bf3bf874c */ ++ 4.81593633223853068159e-01, /* 0x3fded26e1a2a2110 */ ++ 1.70489514001513020602e+00, /* 0x3ffb4740205796d6 */ ++ 1.12416073489841270572e+01, /* 0x40267bb3f55cb85d */ ++ 7.06579578098005001152e+00, /* 0x401c435ff81e18ac */ ++ 5.91244513000686140458e+01, /* 0x404d8fee052bdea4 */ ++ 1.68921736147088438429e+02, /* 0x40651d7edccde926 */ ++ 2.60692936262087528121e+02, /* 0x40704b1644557e0e */ ++ 3.62419382134890611269e+02, /* 0x4076a6b5ca0a9e1c */ ++ 4.07689930834187453002e+03, /* 0x40afd9cc72249abe */ ++ 1.55377375868385224749e+04, /* 0x40ce58de693edab5 */ ++ 2.53720210371943103382e+04, /* 0x40d8c70158ac6364 */ ++ 4.78822310734952334315e+04, /* 0x40e7614764f43e20 */ ++ 1.81871712615542812273e+05, /* 0x4106337db36fc718 */ ++ 5.62892347580489004031e+05, /* 0x41212d98b1f611e2 */ ++ 6.41374032312148716301e+05, /* 0x412392bc108b37cc */ ++ 7.57809544070145115256e+06, /* 0x415ce87bdc3473dc */ ++ 3.64177136406482197344e+06, /* 0x414bc8d5ae99ad14 */ ++ 7.63580561355670914054e+06}; /* 0x415d20d76744835c */ ++ ++ unsigned long ux, aux, xneg; ++ double y, z, z1, z2; ++ int m; ++ ++ /* Special cases */ ++ ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ if (aux < 0x3e30000000000000) /* |x| small enough that sinh(x) = x */ ++ { ++ if (aux == 0) ++ /* with no inexact */ ++ return x; ++ else ++ return val_with_flags(x, AMD_F_INEXACT); ++ } ++ else if (aux >= 0x7ff0000000000000) /* |x| is NaN or Inf */ ++ return x + x; ++ ++ xneg = (aux != ux); ++ ++ y = x; ++ if (xneg) y = -x; ++ ++ if (y >= max_sinh_arg) ++ /* Return +/-infinity with overflow flag */ ++ return retval_errno_erange(x, xneg); ++ else if (y >= small_threshold) ++ { ++ /* In this range y is large enough so that ++ the negative exponential is negligible, ++ so sinh(y) is approximated by sign(x)*exp(y)/2. The ++ code below is an inlined version of that from ++ exp() with two changes (it operates on ++ y instead of x, and the division by 2 is ++ done by reducing m by 1). */ ++ ++ splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, ++ log2_by_32_tail, &m, &z1, &z2); ++ m -= 1; ++ ++ if (m >= EMIN_DP64 && m <= EMAX_DP64) ++ z = scaleDouble_1((z1+z2),m); ++ else ++ z = scaleDouble_2((z1+z2),m); ++ } ++ else ++ { ++ /* In this range we find the integer part y0 of y ++ and the increment dy = y - y0. We then compute ++ ++ z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) ++ ++ where sinh(y0) and cosh(y0) are tabulated above. */ ++ ++ int ind; ++ double dy, dy2, sdy, cdy, sdy1, sdy2; ++ ++ ind = (int)y; ++ dy = y - ind; ++ ++ dy2 = dy*dy; ++ sdy = dy*dy2*(0.166666666666666667013899e0 + ++ (0.833333333333329931873097e-2 + ++ (0.198412698413242405162014e-3 + ++ (0.275573191913636406057211e-5 + ++ (0.250521176994133472333666e-7 + ++ (0.160576793121939886190847e-9 + ++ 0.7746188980094184251527126e-12*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ cdy = dy2*(0.500000000000000005911074e0 + ++ (0.416666666666660876512776e-1 + ++ (0.138888888889814854814536e-2 + ++ (0.248015872460622433115785e-4 + ++ (0.275573350756016588011357e-6 + ++ (0.208744349831471353536305e-8 + ++ 0.1163921388172173692062032e-10*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ /* At this point sinh(dy) is approximated by dy + sdy. ++ Shift some significant bits from dy to sdy. */ ++ ++ GET_BITS_DP64(dy, ux); ++ ux &= 0xfffffffff8000000; ++ PUT_BITS_DP64(ux, sdy1); ++ sdy2 = sdy + (dy - sdy1); ++ ++ z = ((((((cosh_tail[ind]*sdy2 + sinh_tail[ind]*cdy) ++ + cosh_tail[ind]*sdy1) + sinh_tail[ind]) ++ + cosh_lead[ind]*sdy2) + sinh_lead[ind]*cdy) ++ + cosh_lead[ind]*sdy1) + sinh_lead[ind]; ++ } ++ ++ if (xneg) z = - z; ++ return z; ++} ++ ++weak_alias (__sinh, sinh) ++weak_alias (__sinh, __ieee754_sinh) +diff -urpN libc/sysdeps/x86_64/fpu/w_sinhf.c libc-amd/sysdeps/x86_64/fpu/w_sinhf.c +--- libc/sysdeps/x86_64/fpu/w_sinhf.c 1970-01-01 01:00:00.000000000 +0100 ++++ libc-amd/sysdeps/x86_64/fpu/w_sinhf.c 2006-03-22 02:40:46.000000000 +0100 +@@ -0,0 +1,251 @@ ++/* ++(C) 2002 Advanced Micro Devices, Inc. ++** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS ++ AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC ++ LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH ++ THIS LIBRARY** ++*/ ++ ++#include <errno.h> ++#include <stdio.h> ++#include "libm_amd.h" ++#include "libm_util_amd.h" ++ ++#define USE_SPLITEXP ++#define USE_SCALEDOUBLE_1 ++#define USE_SCALEDOUBLE_2 ++#define USE_INFINITY_WITH_FLAGS ++#include "libm_inlines_amd.h" ++#undef USE_SPLITEXP ++#undef USE_SCALEDOUBLE_1 ++#undef USE_SCALEDOUBLE_2 ++#undef USE_INFINITY_WITH_FLAGS ++ ++/* Deal with errno for out-of-range result */ ++static inline float retval_errno_erange(float x, int xneg) ++{ ++ struct exception exc; ++ exc.arg1 = (double)x; ++ exc.arg2 = (double)x; ++ exc.type = OVERFLOW; ++ exc.name = (char *)"sinh"; ++ if (_LIB_VERSION == _SVID_) ++ { ++ if (xneg) ++ exc.retval = -HUGE; ++ else ++ exc.retval = HUGE; ++ } ++ else ++ { ++ if (xneg) ++ exc.retval = -infinity_with_flags(AMD_F_OVERFLOW); ++ else ++ exc.retval = infinity_with_flags(AMD_F_OVERFLOW); ++ } ++ if (_LIB_VERSION == _POSIX_) ++ __set_errno(ERANGE); ++ else if (!matherr(&exc)) ++ __set_errno(ERANGE); ++ return exc.retval; ++} ++ ++float __sinhf(float fx) ++{ ++ /* ++ After dealing with special cases the computation is split into ++ regions as follows: ++ ++ abs(x) >= max_sinh_arg: ++ sinh(x) = sign(x)*Inf ++ ++ abs(x) >= small_threshold: ++ sinh(x) = sign(x)*exp(abs(x))/2 computed using the ++ splitexp and scaleDouble functions as for exp_amd(). ++ ++ abs(x) < small_threshold: ++ compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0))) ++ sinh(x) is then sign(x)*z. */ ++ ++ static const double ++ /* The max argument of sinhf, but stored as a double */ ++ max_sinh_arg = 8.94159862922329438106e+01, /* 0x40565a9f84f82e63 */ ++ thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ ++ log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ ++ log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */ ++ small_threshold = 8*BASEDIGITS_DP64*0.30102999566398119521373889; ++ /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */ ++ ++ /* Tabulated values of sinh(i) and cosh(i) for i = 0,...,36. */ ++ ++ static const double sinh_lead[ 37] = { ++ 0.00000000000000000000e+00, /* 0x0000000000000000 */ ++ 1.17520119364380137839e+00, /* 0x3ff2cd9fc44eb982 */ ++ 3.62686040784701857476e+00, /* 0x400d03cf63b6e19f */ ++ 1.00178749274099008204e+01, /* 0x40240926e70949ad */ ++ 2.72899171971277496596e+01, /* 0x403b4a3803703630 */ ++ 7.42032105777887522891e+01, /* 0x40528d0166f07374 */ ++ 2.01713157370279219549e+02, /* 0x406936d22f67c805 */ ++ 5.48316123273246489589e+02, /* 0x408122876ba380c9 */ ++ 1.49047882578955000099e+03, /* 0x409749ea514eca65 */ ++ 4.05154190208278987484e+03, /* 0x40afa7157430966f */ ++ 1.10132328747033916443e+04, /* 0x40c5829dced69991 */ ++ 2.99370708492480553105e+04, /* 0x40dd3c4488cb48d6 */ ++ 8.13773957064298447222e+04, /* 0x40f3de1654d043f0 */ ++ 2.21206696003330085659e+05, /* 0x410b00b5916a31a5 */ ++ 6.01302142081972560845e+05, /* 0x412259ac48bef7e3 */ ++ 1.63450868623590236530e+06, /* 0x4138f0ccafad27f6 */ ++ 4.44305526025387924165e+06, /* 0x4150f2ebd0a7ffe3 */ ++ 1.20774763767876271158e+07, /* 0x416709348c0ea4ed */ ++ 3.28299845686652474105e+07, /* 0x417f4f22091940bb */ ++ 8.92411504815936237574e+07, /* 0x419546d8f9ed26e1 */ ++ 2.42582597704895108938e+08, /* 0x41aceb088b68e803 */ ++ 6.59407867241607308388e+08, /* 0x41c3a6e1fd9eecfd */ ++ 1.79245642306579566002e+09, /* 0x41dab5adb9c435ff */ ++ 4.87240172312445068359e+09, /* 0x41f226af33b1fdc0 */ ++ 1.32445610649217357635e+10, /* 0x4208ab7fb5475fb7 */ ++ 3.60024496686929321289e+10, /* 0x4220c3d3920962c8 */ ++ 9.78648047144193725586e+10, /* 0x4236c932696a6b5c */ ++ 2.66024120300899291992e+11, /* 0x424ef822f7f6731c */ ++ 7.23128532145737548828e+11, /* 0x42650bba3796379a */ ++ 1.96566714857202099609e+12, /* 0x427c9aae4631c056 */ ++ 5.34323729076223046875e+12, /* 0x429370470aec28ec */ ++ 1.45244248326237109375e+13, /* 0x42aa6b765d8cdf6c */ ++ 3.94814800913403437500e+13, /* 0x42c1f43fcc4b662c */ ++ 1.07321789892958031250e+14, /* 0x42d866f34a725782 */ ++ 2.91730871263727437500e+14, /* 0x42f0953e2f3a1ef7 */ ++ 7.93006726156715250000e+14, /* 0x430689e221bc8d5a */ ++ 2.15561577355759750000e+15}; /* 0x431ea215a1d20d76 */ ++ ++ static const double cosh_lead[ 37] = { ++ 1.00000000000000000000e+00, /* 0x3ff0000000000000 */ ++ 1.54308063481524371241e+00, /* 0x3ff8b07551d9f550 */ ++ 3.76219569108363138810e+00, /* 0x400e18fa0df2d9bc */ ++ 1.00676619957777653269e+01, /* 0x402422a497d6185e */ ++ 2.73082328360164865444e+01, /* 0x403b4ee858de3e80 */ ++ 7.42099485247878334349e+01, /* 0x40528d6fcbeff3a9 */ ++ 2.01715636122455890700e+02, /* 0x406936e67db9b919 */ ++ 5.48317035155212010977e+02, /* 0x4081228949ba3a8b */ ++ 1.49047916125217807348e+03, /* 0x409749eaa93f4e76 */ ++ 4.05154202549259389343e+03, /* 0x40afa715845d8894 */ ++ 1.10132329201033226127e+04, /* 0x40c5829dd053712d */ ++ 2.99370708659497577173e+04, /* 0x40dd3c4489115627 */ ++ 8.13773957125740562333e+04, /* 0x40f3de1654d6b543 */ ++ 2.21206696005590405548e+05, /* 0x410b00b5916b6105 */ ++ 6.01302142082804115489e+05, /* 0x412259ac48bf13ca */ ++ 1.63450868623620807193e+06, /* 0x4138f0ccafad2d17 */ ++ 4.44305526025399193168e+06, /* 0x4150f2ebd0a8005c */ ++ 1.20774763767876680940e+07, /* 0x416709348c0ea503 */ ++ 3.28299845686652623117e+07, /* 0x417f4f22091940bf */ ++ 8.92411504815936237574e+07, /* 0x419546d8f9ed26e1 */ ++ 2.42582597704895138741e+08, /* 0x41aceb088b68e804 */ ++ 6.59407867241607308388e+08, /* 0x41c3a6e1fd9eecfd */ ++ 1.79245642306579566002e+09, /* 0x41dab5adb9c435ff */ ++ 4.87240172312445068359e+09, /* 0x41f226af33b1fdc0 */ ++ 1.32445610649217357635e+10, /* 0x4208ab7fb5475fb7 */ ++ 3.60024496686929321289e+10, /* 0x4220c3d3920962c8 */ ++ 9.78648047144193725586e+10, /* 0x4236c932696a6b5c */ ++ 2.66024120300899291992e+11, /* 0x424ef822f7f6731c */ ++ 7.23128532145737548828e+11, /* 0x42650bba3796379a */ ++ 1.96566714857202099609e+12, /* 0x427c9aae4631c056 */ ++ 5.34323729076223046875e+12, /* 0x429370470aec28ec */ ++ 1.45244248326237109375e+13, /* 0x42aa6b765d8cdf6c */ ++ 3.94814800913403437500e+13, /* 0x42c1f43fcc4b662c */ ++ 1.07321789892958031250e+14, /* 0x42d866f34a725782 */ ++ 2.91730871263727437500e+14, /* 0x42f0953e2f3a1ef7 */ ++ 7.93006726156715250000e+14, /* 0x430689e221bc8d5a */ ++ 2.15561577355759750000e+15}; /* 0x431ea215a1d20d76 */ ++ ++ unsigned long ux, aux, xneg; ++ double x = fx, y, z, z1, z2; ++ int m; ++ ++ /* Special cases */ ++ ++ GET_BITS_DP64(x, ux); ++ aux = ux & ~SIGNBIT_DP64; ++ if (aux < 0x3f10000000000000) /* |x| small enough that sinh(x) = x */ ++ { ++ if (aux == 0) return x; /* with no inexact */ ++ if (LAMBDA_DP64 + x > 1.0) return x; /* with inexact */ ++ } ++ else if (aux >= 0x7ff0000000000000) /* |x| is NaN or Inf */ ++ return x + x; ++ ++ xneg = (aux != ux); ++ ++ y = x; ++ if (xneg) y = -x; ++ ++ if (y >= max_sinh_arg) ++ { ++ /* Return infinity with overflow flag. */ ++#if 0 ++ /* This way handles non-POSIX behaviour but weirdly causes ++ sinhf to run half as fast for all arguments on Hammer */ ++ return retval_errno_erange(fx, xneg); ++#else ++ /* This handles POSIX behaviour */ ++ __set_errno(ERANGE); ++ z = infinity_with_flags(AMD_F_OVERFLOW); ++#endif ++ } ++ else if (y >= small_threshold) ++ { ++ /* In this range y is large enough so that ++ the negative exponential is negligible, ++ so sinh(y) is approximated by sign(x)*exp(y)/2. The ++ code below is an inlined version of that from ++ exp() with two changes (it operates on ++ y instead of x, and the division by 2 is ++ done by reducing m by 1). */ ++ ++ splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead, ++ log2_by_32_tail, &m, &z1, &z2); ++ m -= 1; ++ /* scaleDouble_1 is always safe because the argument x was ++ float, rather than double */ ++ z = scaleDouble_1((z1+z2),m); ++ } ++ else ++ { ++ /* In this range we find the integer part y0 of y ++ and the increment dy = y - y0. We then compute ++ ++ z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) ++ ++ where sinh(y0) and cosh(y0) are tabulated above. */ ++ ++ int ind; ++ double dy, dy2, sdy, cdy; ++ ++ ind = (int)y; ++ dy = y - ind; ++ ++ dy2 = dy*dy; ++ ++ sdy = dy + dy*dy2*(0.166666666666666667013899e0 + ++ (0.833333333333329931873097e-2 + ++ (0.198412698413242405162014e-3 + ++ (0.275573191913636406057211e-5 + ++ (0.250521176994133472333666e-7 + ++ (0.160576793121939886190847e-9 + ++ 0.7746188980094184251527126e-12*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ cdy = 1 + dy2*(0.500000000000000005911074e0 + ++ (0.416666666666660876512776e-1 + ++ (0.138888888889814854814536e-2 + ++ (0.248015872460622433115785e-4 + ++ (0.275573350756016588011357e-6 + ++ (0.208744349831471353536305e-8 + ++ 0.1163921388172173692062032e-10*dy2)*dy2)*dy2)*dy2)*dy2)*dy2); ++ ++ z = sinh_lead[ind]*cdy + cosh_lead[ind]*sdy; ++ } ++ ++ if (xneg) z = - z; ++ return z; ++} ++ ++weak_alias (__sinhf, sinhf) ++weak_alias (__sinhf, __ieee754_sinhf) diff --git a/patches/glibc-2.5/generic/oe/arm-longlong.patch b/patches/glibc-2.5/generic/glibc-2.5_stdlib_longlong.h index a8e529f..b7223d6 100644 --- a/patches/glibc-2.5/generic/oe/arm-longlong.patch +++ b/patches/glibc-2.5/generic/glibc-2.5_stdlib_longlong.h @@ -1,5 +1,3 @@ -Index: glibc-2.5/stdlib/longlong.h -=================================================================== --- glibc-2.5.orig/stdlib/longlong.h +++ glibc-2.5/stdlib/longlong.h @@ -205,6 +205,14 @@ UDItype __umulsidi3 (USItype, USItype); @@ -33,30 +31,3 @@ Index: glibc-2.5/stdlib/longlong.h #if defined (__hppa) && W_TYPE_SIZE == 32 Index: glibc-2.5/ports/sysdeps/arm/mp_clz_tab.c =================================================================== ---- /dev/null -+++ glibc-2.5/ports/sysdeps/arm/mp_clz_tab.c -@@ -0,0 +1,24 @@ -+/* __clz_tab -- support for longlong.h -+ Copyright (C) 2004 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. */ -+ -+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) -+/* Nothing required. */ -+#else -+#include <stdlib/mp_clz_tab.c> -+#endif diff --git a/patches/glibc-2.5/generic/glibc-configure-apple-as.patch b/patches/glibc-2.5/generic/glibc-configure-apple-as.patch index 23db4ff..d6f77e2 100644 --- a/patches/glibc-2.5/generic/glibc-configure-apple-as.patch +++ b/patches/glibc-2.5/generic/glibc-configure-apple-as.patch @@ -10,11 +10,15 @@ checking for /usr/libexec/gcc/darwin/ppc/as... /usr/libexec/gcc/darwin/ppc/as checking version of /usr/libexec/gcc/darwin/ppc/as... <PAUSES HERE AND JUST SITS THERE DOING NOTHING> +--- + configure | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + Index: glibc-2.5/configure =================================================================== ---- glibc-2.5.orig/configure 2008-03-08 10:27:55.000000000 +0100 -+++ glibc-2.5/configure 2008-03-08 10:28:12.000000000 +0100 -@@ -4041,7 +4041,7 @@ +--- glibc-2.5.orig/configure ++++ glibc-2.5/configure +@@ -4039,7 +4039,7 @@ else # Found it, now check the version. echo "$as_me:$LINENO: checking version of $AS" >&5 echo $ECHO_N "checking version of $AS... $ECHO_C" >&6 @@ -22,8 +26,8 @@ Index: glibc-2.5/configure + ac_prog_version=`$AS -v </dev/null 2>&1 | sed -n 's/^.*GNU assembler.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 2.1[7-9]* | 2.[2-9][0-9]* | [3-9].*) -@@ -4052,7 +4052,7 @@ + 2.1[3-9]*) +@@ -4050,7 +4050,7 @@ echo $ECHO_N "checking version of $AS... echo "$as_me:$LINENO: result: $ac_prog_version" >&5 echo "${ECHO_T}$ac_prog_version" >&6 fi @@ -32,7 +36,7 @@ Index: glibc-2.5/configure AS=: critic_missing="$critic_missing as" fi -@@ -4113,7 +4113,7 @@ +@@ -4111,7 +4111,7 @@ echo $ECHO_N "checking version of $LD... echo "$as_me:$LINENO: result: $ac_prog_version" >&5 echo "${ECHO_T}$ac_prog_version" >&6 fi diff --git a/patches/glibc-2.5/generic/glibc-configure-old-gcc.patch b/patches/glibc-2.5/generic/glibc-configure-old-gcc.patch index b72bdd2..f328412 100644 --- a/patches/glibc-2.5/generic/glibc-configure-old-gcc.patch +++ b/patches/glibc-2.5/generic/glibc-configure-old-gcc.patch @@ -1,8 +1,12 @@ +--- + configure | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + Index: glibc-2.5/configure =================================================================== ---- glibc-2.5.orig/configure 2008-03-08 10:28:12.000000000 +0100 -+++ glibc-2.5/configure 2008-03-08 10:28:18.000000000 +0100 -@@ -4229,7 +4229,7 @@ +--- glibc-2.5.orig/configure ++++ glibc-2.5/configure +@@ -4226,7 +4226,7 @@ echo $ECHO_N "checking version of $CC... echo "$as_me:$LINENO: result: $ac_prog_version" >&5 echo "${ECHO_T}$ac_prog_version" >&6 fi diff --git a/patches/glibc-2.5/generic/local-2.6.19-linux-libc-dev.diff b/patches/glibc-2.5/generic/local-2.6.19-linux-libc-dev.diff deleted file mode 100644 index e984419..0000000 --- a/patches/glibc-2.5/generic/local-2.6.19-linux-libc-dev.diff +++ /dev/null @@ -1,82 +0,0 @@ -# -# Submitted-By: Marc Kleine-Budde, 2006-11-23 -# Committed-By: Marc Kleine-Budde -# -# Error: -# -# glibc cannot be compiled with samitized headers from 2.6.19rc6 -# -# Description: -# -# http://sourceware.org/ml/libc-alpha/2006-10/msg00024.html -# -# State: -# -# this patch is from ubuntu's glibc-2.5 patch: -# https://patches.ubuntu.com/g/glibc/glibc_2.5-0ubuntu2.patch -# - -# DP: Description: Add missing bits in 2.6.19 kernel headers -# DP: Author: Jeff Bailey <jbailey@ubuntu.com> -# DP: Upstream status: Not Submitted. -# DP: Status Details: No response on http://sourceware.org/ml/libc-alpha/2006-10/msg00024.html -# DP: Date: 2006-10-27 - -Index: glibc-2.5/sysdeps/unix/sysv/linux/check_pf.c -=================================================================== ---- glibc-2.5.orig/sysdeps/unix/sysv/linux/check_pf.c -+++ glibc-2.5/sysdeps/unix/sysv/linux/check_pf.c -@@ -30,10 +30,15 @@ - #include <asm/types.h> - #include <linux/netlink.h> - #include <linux/rtnetlink.h> -+#include <linux/if_addr.h> - - #include <not-cancel.h> - #include <kernel-features.h> - -+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) -+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) -+#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) -+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg)) - - #ifndef IFA_F_TEMPORARY - # define IFA_F_TEMPORARY IFA_F_SECONDARY -Index: glibc-2.5/sysdeps/unix/sysv/linux/if_index.c -=================================================================== ---- glibc-2.5.orig/sysdeps/unix/sysv/linux/if_index.c -+++ glibc-2.5/sysdeps/unix/sysv/linux/if_index.c -@@ -28,9 +28,14 @@ - #include <sys/ioctl.h> - #include <bits/libc-lock.h> - #include <not-cancel.h> -+#include <linux/if_addr.h> - - #include "netlinkaccess.h" - -+#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) -+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg)) -+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) -+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) - - /* Variable to signal whether SIOCGIFCONF is not available. */ - # if __ASSUME_SIOCGIFNAME == 0 -Index: glibc-2.5/sysdeps/unix/sysv/linux/ifaddrs.c -=================================================================== ---- glibc-2.5.orig/sysdeps/unix/sysv/linux/ifaddrs.c -+++ glibc-2.5/sysdeps/unix/sysv/linux/ifaddrs.c -@@ -33,9 +33,14 @@ - #include <sysdep.h> - #include <time.h> - #include <unistd.h> -+#include <linux/if_addr.h> - - #include "netlinkaccess.h" - -+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) -+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) -+#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) -+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg)) - - /* We don't know if we have NETLINK support compiled in in our - Kernel, so include the old implementation as fallback. */ diff --git a/patches/glibc-2.5/generic/make-install-lib-all.patch b/patches/glibc-2.5/generic/make-install-lib-all.patch index 4c0e202..61246b9 100644 --- a/patches/glibc-2.5/generic/make-install-lib-all.patch +++ b/patches/glibc-2.5/generic/make-install-lib-all.patch @@ -13,11 +13,15 @@ # Foundation; either version 2 of the License, or (at your option) any later # version. # --- T2-COPYRIGHT-NOTE-END --- +--- +# Makerules | 8 ++++++++ +# 1 file changed, 8 insertions(+) +# Index: glibc-2.5/Makerules =================================================================== ---- glibc-2.5.orig/Makerules 2008-03-08 10:27:55.000000000 +0100 -+++ glibc-2.5/Makerules 2008-03-08 10:27:59.000000000 +0100 -@@ -875,6 +875,13 @@ +--- glibc-2.5.orig/Makerules ++++ glibc-2.5/Makerules +@@ -864,6 +864,13 @@ endef installed-libcs := $(foreach o,$(filter-out .os,$(object-suffixes-for-libc)),\ $(inst_libdir)/$(patsubst %,$(libtype$o),\ $(libprefix)$(libc-name))) @@ -31,7 +35,7 @@ Index: glibc-2.5/Makerules install: $(installed-libcs) $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force) $(make-target-directory) -@@ -898,6 +905,7 @@ +@@ -887,6 +894,7 @@ endef install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so)) install-lib := $(filter-out %.so %_pic.a,$(install-lib)) diff --git a/patches/glibc-2.5/generic/series b/patches/glibc-2.5/generic/series index 91902ae..6afd632 100644 --- a/patches/glibc-2.5/generic/series +++ b/patches/glibc-2.5/generic/series @@ -4,6 +4,22 @@ glibc-configure-old-gcc.patch configure_in-sane_readelf.diff configure-sane_readelf.diff -#sysdeps_unix_sysv_linux_getcwd_c-include-sys_param_h.diff -cross_timezone.diff -p0 -#local-2.6.19-linux-libc-dev.diff +glibc-2.5_stdlib_longlong.h + +gentoo/0030_all_glibc-respect-env-CPPFLAGS.patch +gentoo/1010_all_glibc-cvs-update-MINOR.patch +gentoo/1015_all_glibc-2.5-realloc-assert.patch +gentoo/1025_all_glibc-2.5-getusershell-fixes.patch +gentoo/1035_all_glibc-cvs-fix-fork-handler-refcount-in-child.patch +gentoo/1050_all_glibc-fix-printf-overflow-with-large-precisions.patch +gentoo/1055_all_glibc-resolv-dynamic.patch +gentoo/1060_all_glibc-cvs-getcwd-path-max.patch +gentoo/1075_all_glibc-section-comments.patch +gentoo/1090_all_glibc-2.3.6-fix-pr631.patch +gentoo/1100_all_glibc-2.3.3-china.patch +gentoo/1120_all_glibc-2.5-strict-aliasing.patch +gentoo/1130_all_glibc-2.4-undefine-__i686.patch +gentoo/1160_all_glibc-2.5-filter-files-for-headers-test.patch +gentoo/1600_all_glibc-hwcap-mask-secure.patch + +cross_timezone.diff |