diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2012-10-10 15:35:46 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2012-10-10 15:35:46 +0000 |
commit | 2d32c4f00084f68a390e8fa4291acb49e9c0df8e (patch) | |
tree | 00964019e9307917f730b8c6b817f0cb9496a167 | |
parent | 7dfcd4332472afda13e2ea9c0eaba15a08d8351e (diff) | |
download | eglibc2-2d32c4f00084f68a390e8fa4291acb49e9c0df8e.tar.gz |
Merge changes between r20863 and r21108 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@21109 7b3dc134-2b1b-0410-93df-9e9f96275f8d
249 files changed, 6713 insertions, 3543 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog index cea98d16a..a3e846e34 100644 --- a/libc/ChangeLog +++ b/libc/ChangeLog @@ -1,3 +1,556 @@ +2012-10-09 Joseph Myers <joseph@codesourcery.com> + + * math/gen-libm-test.pl (parse_args): Handle comparison macros as + type-generic. + * math/libm-test.inc: Update comment listing what functions and + macros are tested. + (isgreater_test): New function. + (isgreaterequal_test): Likewise. + (isless_test): Likewise. + (islessequal_test): Likewise. + (islessgreater_test): Likewise. + (isunordered_test): Likewise. + (main): Call the new functions. + +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * aclocal.m4 (GLIBC_PROVIDES): Provide _AS_BASENAME_PREPARE, + _AS_ME_PREPARE, _AS_VAR_ARITH_PREPARE, AS_SHELL_FN_as_fn_set_status, + AS_SHELL_FN_as_fn_exit, AS_SHELL_FN_ac_fn_c_try_compile. + * sysdeps/i386/configure: Regenerated. + * sysdeps/ieee754/ldbl-opt/configure: Regenerated. + * sysdeps/mach/configure: Regenerated. + * sysdeps/mach/hurd/configure: Regenerated. + * sysdeps/powerpc/configure: Regenerated. + * sysdeps/powerpc/powerpc32/configure: Regenerated. + * sysdeps/powerpc/powerpc64/configure: Regenerated. + * sysdeps/s390/s390-32/configure: Regenerated. + * sysdeps/s390/s390-64/configure: Regenerated. + * sysdeps/sh/configure: Regenerated. + * sysdeps/sparc/configure: Regenerated. + * sysdeps/unix/sysv/linux/configure: Regenerated. + * sysdeps/unix/sysv/linux/powerpc/configure: Regenerated. + * sysdeps/x86_64/configure: Regenerated. + + * dlfcn/dlerror.c (check_free): Call _dl_addr only if SHARED is + defined. Don't check if MAP is NULL. + +2012-10-09 Joseph Myers <joseph@codesourcery.com> + + * sysdeps/generic/_G_config.h (_G_off64_t): Remove. + (_G_stat64): Likewise. + * sysdeps/unix/sysv/linux/_G_config.h (_G_off64_t): Remove. + (_G_stat64): Likewise. + * libio/filedoalloc.c (_IO_file_doallocate): Use struct stat64 + instead of struct _G_stat64. + * libio/fileops.c (mmap_remap_check): Likewise. + (decide_maybe_mmap): Likewise. + (_IO_new_file_seekoff): Likewise. + (_IO_file_stat): Likewise. + * libio/libio.h (_IO_off64_t): Define to __off64_t, not + _G_off64_t. + * libio/oldfileops.c (_IO_old_file_seekoff): Use struct stat64 + instead of struct _G_stat64. + * libio/wfileops.c (_IO_wfile_seekoff): Likewise. + +2012-10-08 Maxim Kuvyrkov <maxim@codesourcery.com> + + [BZ #14602] + * string/str-two-way.h (AVAILABLE1, AVAILABLE2, AVAILABLE1_USES_J): + Replace with ... + (CHECK_EOL): New macro. + (two_way_short_needle): Check beginning of haystack for EOL. Use + CHECK_EOL. + * string/strcasestr.c (AVAILABLE1, AVAILABLE2, AVAILABLE1_USES_J): + Replace with CHECK_EOL. + * string/strstr.c (AVAILABLE1, AVAILABLE2, AVAILABLE1_USES_J): + Replace with CHECK_EOL. + +2012-10-08 Joseph Myers <joseph@codesourcery.com> + + * math/gen-libm-test.pl (parse_args): Handle isinf and isnan as + type-generic. + * math/libm-test.inc: Update comment listing what functions and + macros are tested. + (finite_test): New function. + (isinf_test): Likewise. + (isnan_test): Likewise. + (fpclassify_test): Test subnormal input. + (isfinite_test): Likewise. + (isnormal_test): Likewise. + (main): Call the new functions. + +2012-10-08 Jonathan Nieder <jrnieder@gmail.com> + + [BZ #14660] + * Makerules (%.dynsym): Force C locale when running + $(OBJDUMP) --dynamic-syms. + +2012-10-08 Andreas Schwab <schwab@linux-m68k.org> + + * sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: Include + <stdint.h>. + +2012-10-06 David S. Miller <davem@davemloft.net> + + * sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S: On 32-bit, clear + upper 32-bits of the length value in %o2 since we use branch-on-register + tests which consider the entire 64-bit register. + +2012-10-06 H.J. Lu <hongjiu.lu@intel.com> + + * string/test-strstr.c (check2): Add a test for page boundary. + +2012-10-05 David S. Miller <davem@davemloft.net> + + * sysdeps/sparc/sparc64/multiarch/memset-niagara4.S: New file. + * sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S: New + file. + * sysdeps/sparc/sparc64/multiarch/Makefile: Add to + sysdep_routines. + * sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile: Likewise. + * sysdeps/sparc/sparc64/multiarch/memset.S: Use Niagara-4 memset + and bzero when HWCAP_SPARC_CRYPTO is present. + +2012-10-05 H.J. Lu <hongjiu.lu@intel.com> + + [BZ #14602] + * string/test-strstr.c (check2): New function. + (test_main): Call check2. + + * string/Makefile (tests): Remove bug-strstr1, bug-strcasestr1 + and bug-strchr1. + * string/bug-strcasestr1.c (do_test): Moved to ... + * string/test-strcasestr.c (check1): Here. New function. + (do_one_test): Break out result checking code into ... + (check_result): This. New function. + (do_one_test): Call check_result. + (test_main): Call check1. + * string/bug-strchr1.c (do_test): Moved to ... + * string/test-strchr.c (check1): Here. New function. + (do_one_test): Break out result checking code into ... + (check_result): This. New function. + (do_one_test): Call check_result. + (test_main): Call check1. + * string/bug-strstr1.c (main): Moved to ... + * string/test-strchr.c (check1): Here. New function. + (do_one_test): Break out result checking code into ... + (check_result): This. New function. + (do_one_test): Call check_result. + (test_main): Call check1. + * string/bug-strcasestr1.c: Removed. + * string/bug-strchr1.c: Likewise. + * string/bug-strstr1.c: Likewise. + + * elf/Makefile (dl-routines): Add hwcaps. + * elf/dl-support.c (_dl_important_hwcaps): Removed. + * elf/dl-sysdep.c (_DL_FIRST_EXTRA): Likewise. + (_dl_important_hwcaps): Moved to ... + * elf/dl-hwcaps.c: Here. New file. + * sysdeps/mach/hurd/dl-sysdep.c (_dl_important_hwcaps): Removed. + + [BZ #14557] + * elf/setup-vdso.h (setup_vdso): Set GL(dl_nns) to 1 for vDSO + if IS_IN_rtld isn't defined. + + * elf/dl-support.c (_dl_sysinfo_map): New. + Include "get-dynamic-info.h" and "setup-vdso.h". + (_dl_non_dynamic_init): Call setup_vdso. + * elf/dynamic-link.h: Don't include <assert.h>. + (elf_get_dynamic_info): Moved to ... + * elf/get-dynamic-info.h: Here. New file. + * elf/dynamic-link.h: Include "get-dynamic-info.h". + * elf/rtld.c (dl_main): Break out vDSO setup code into ... + * elf/setup-vdso.h: Here. New file. + * elf/rtld.c: Include "setup-vdso.h". + (dl_main): Call setup_vdso. + +2012-10-05 Joseph Myers <joseph@codesourcery.com> + + * math/libm-test.inc: List nexttoward, cimag, clog10, conf and + creal in comment listing functions tested. List finite, isinf, + isnan, isless, islessequal, isgreater, isgreaterequal, + islessgreater, isunordered, lgamma_r and pow10 as functions and + macros not tested. Mention which functions not tested are aliases + for other functions. Fix typo. Note that signs of NaNs are not + tested. + + * scripts/config.guess: Update from config.git. + * scripts/config.sub: Likewise. + +2012-10-04 Roland McGrath <roland@hack.frob.com> + + * misc/Versions (GLIBC_PRIVATE): New set, add __madvise. + * misc/madvise.c (madvise): Renamed to __madvise. + Make madvise a weak alias. + * include/sys/mman.h: Declare __madvise. + Replace libc_hidden_proto (madvise) with libc_hidden_proto (__madvise). + * sysdeps/unix/syscalls.list + (madvise): Make __madvise the strong name, and madvise a weak alias. + * sysdeps/unix/sysv/linux/syscalls.list + (madvise, mmap): Remove redundant entries. + * malloc/arena.c (shrink_heap): Use __madvise, not madvise. + * malloc/malloc.c (mtrim): Likewise. + * sysdeps/mach/hurd/malloc-machine.h (madvise): Renamed to __madvise. + +2012-10-03 Roland McGrath <roland@hack.frob.com> + + * sysdeps/mach/hurd/dl-cache.c: File removed. + * config.h.in (USE_LDCONFIG): New #undef. + * configure.in (use_ldconfig): If set, define USE_LDCONFIG. + * configure: Regenerated. + * elf/Makefile (dl-routines): Add dl-cache only under + [$(use-ldconfig) = yes]. + * elf/dl-load.c (_dl_map_object): Conditionalize code consulting the + cache on [USE_LDCONFIG]. + * elf/dl-open.c (_dl_open): Call _dl_unload_cache only under + [USE_LDCONFIG]. + * elf/rtld.c (dl_main): Likewise. + +2012-10-03 Pino Toscano <toscano.pino@tiscali.it> + + * sysdeps/posix/sysconf.c (__sysconf): Return 0 also for + _SC_LEVEL4_CACHE_LINESIZE. + +2012-10-03 Roland McGrath <roland@hack.frob.com> + + * sysdeps/unix/bsd/confstr.h: File removed. + +2012-10-02 Alexandre Oliva <aoliva@redhat.com> + + * scripts/check-local-headers.sh: Exclude sys/sdt.h and + sys/sdt-config.h. + +2012-10-02 Roland McGrath <roland@hack.frob.com> + + * elf/dl-load.c (_dl_map_object_from_fd: struct loadcmd): + Make 'mapoff' field ElfW(Off) rather than off_t. + +2012-10-02 Dmitry V. Levin <ldv@altlinux.org> + + * nscd/Makefile: Remove nscd-cflags and all its users. + (CPPFLAGS-nonlib): Add preprocessor flags for nscd modules. + (CFLAGS-nonlib): Add compiler flags for nscd modules. + + [BZ #10631] + * malloc.c (malloc_printerr): Clarify error message. + +2012-10-02 H.J. Lu <hongjiu.lu@intel.com> + + [BZ #14648] + * sysdeps/x86_64/multiarch/init-arch.c (__init_cpu_features): + Set bit_FMA_Usable if FMA is supported. + * sysdeps/x86_64/multiarch/init-arch.h (bit_FMA_Usable): New + macro. + (bit_FMA4_Usable): Updated. + (index_FMA_Usable): New macro. + (CPUID_FMA): Likewise + (HAS_FMA): Defined with bit_FMA_Usable. + +2012-10-01 Roland McGrath <roland@hack.frob.com> + + * bits/types.h (__swblk_t): Type removed. + * bits/typesizes.h (__SWBLK_T_TYPE): Macro removed. + * sysdeps/mach/hurd/bits/typesizes.h (__SWBLK_T_TYPE): Likewise. + * sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h + (__SWBLK_T_TYPE): Likewise. + * sysdeps/unix/sysv/linux/x86/bits/typesizes.h + (__SWBLK_T_TYPE): Likewise. + * sysdeps/unix/sysv/linux/sparc/bits/typesizes.h + (__SWBLK_T_TYPE): Likewise. + * sysdeps/unix/sysv/linux/s390/bits/typesizes.h + (__SWBLK_T_TYPE): Likewise. + +2012-10-01 Patsy Franklin <pfrankli@redhat.com> + Honza Horak <hhorak@redhat.com> + + * nis/yp_xdr.c (xdr_domainname): Use YPMAXDOMAIN as maxsize. + (xdr_mapname): Use YPMAXMAP as maxsize. + (xdr_peername): Use YPMAXPEER as maxsize. + (xdr_keydat): Use YPAXRECORD as maxsize. + (xdr_valdat): Use YPMAXRECORD as maxsize. + +2012-10-01 Roland McGrath <roland@hack.frob.com> + + * io/openat.c [!__ASSUME_ATFCTS] (__have_atfcts): New global variable. + + * sysdeps/unix/sysv/linux/init-first.c: Moved to ... + * csu/init-first.c: ... here. + * sysdeps/unix/sysv/linux/powerpc/init-first.c: Update #include. + * sysdeps/unix/sysv/linux/s390/init-first.c: Likewise. + * sysdeps/unix/sysv/linux/x86_64/init-first.c: Likewise. + * sysdeps/unix/sysv/linux/x86_64/x32/init-first.c: Likewise. + * sysdeps/i386/init-first.c: File removed. + * sysdeps/sh/init-first.c: File removed. + +2012-10-01 Joseph Myers <joseph@codesourcery.com> + + [BZ #14645] + * sysdeps/ieee754/dbl-64/s_fma.c (__fma): Compute result as x * y + if x * y might underflow to zero and z is zero. + * sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Likewise. + * sysdeps/ieee754/ldbl-96/s_fmal.c (__fmal): Likewise. + * math/libm-test.inc (min_subnorm_value): New variable. + (fma_test): Add more tests. + (fma_test_towardzero): Likewise. + (fma_test_downward): Likewise + (fma_test_upward): Likewise. + (initialize): Set min_subnorm_value. + +2012-09-29 Joseph Myers <joseph@codesourcery.com> + + [BZ #14638] + * sysdeps/ieee754/dbl-64/s_fma.c (__fma): Use x * y + z for exact + 0 + 0. + * sysdeps/ieee754/dbl-64/s_fmaf.c (__fmaf): Use original rounding + mode for addition resulting in exact zero. + * sysdeps/ieee754/ldbl-128/s_fma.c (__fma): Likewise. + * sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Use x * y + z for + exact 0 + 0. + * sysdeps/ieee754/ldbl-96/s_fma.c (__fma): Likewise. + * sysdeps/ieee754/ldbl-96/s_fmal.c (__fmal): Likewise. + * math/libm-test.inc (fma_test): Add more tests. + (fma_test_towardzero): New function. + (fma_test_downward): Likewise. + (fma_test_upward): Likewise. + (main): Call the new functions. + +2012-09-28 David S. Miller <davem@davemloft.net> + + * sysdeps/sparc/fpu/libm-test-ulps: Fix garbage in file. + +2012-09-28 Roland McGrath <roland@hack.frob.com> + + * sysdeps/posix/sleep.c (__sleep): Rewritten using __nanosleep + instead of SIGALRM. + + * sysdeps/gnu/_G_config.h: Moved to ... + * sysdeps/unix/sysv/linux/_G_config.h: ... here. + * sysdeps/mach/hurd/_G_config.h: Moved to ... + * sysdeps/generic/_G_config.h: ... here. + + * io/open.c (__open): Renamed to __libc_open. Make __open an alias. + + * posix/Makefile ($(objpfx)config-name.h): Do $(make-target-directory). + + * nss/Makefile ($(objpfx)/libnss_test1.so$(libnss_test1.so-version)): + Conditionalize target on [libnss_test1.so-version]. + + * elf/dl-sysdep.c: Conditionalize whole contents on [SHARED]. + + * Makeconfig (nssobjdir, resolvobjdir): Remove variables. + (elfobjdir): Move out of conditionals. + + * nss/nsswitch.c (nss_new_service): Conditionalize definition and + declaration on [!DO_STATIC_NSS || SHARED], matching its only caller. + (__nss_lookup_function): Conditionalize label remove_from_tree on + [!DO_STATIC_NSS || SHARED], matching its only use. + +2012-09-28 David S. Miller <davem@davemloft.net> + + * sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S: New file. + * sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S: New + file. + * sysdeps/sparc/sparc64/multiarch/Makefile: Add to + sysdep_routines. + * sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy.S: Use Niagara-4 memcpy + when HWCAP_SPARC_CRYPTO is present. + +2012-09-28 Pino Toscano <toscano.pino@tiscali.it> + + * io/tst-mknodat.c: Create a FIFO instead of a socket. + +2012-09-28 Andreas Schwab <schwab@linux-m68k.org> + + [BZ #6530] + * stdio-common/vfprintf.c (process_string_arg): Revert + 2000-07-22 change. + +2011-09-28 Jonathan Nieder <jrnieder@gmail.com> + + * stdio-common/Makefile (tst-sprintf-ENV): Set environment + for testcase. + * stdio-common/tst-sprintf.c: Include <locale.h> + (main): Test sprintf's handling of incomplete multibyte + characters. + +2012-09-28 H.J. Lu <hongjiu.lu@intel.com> + + * elf/dl-runtime.c (VERSYMIDX): Removed. + * elf/dl-version.c (VERSYMIDX): Likewise. + * elf/do-rel.h (VERSYMIDX): Likewise. + (VALIDX): Likewise. + * elf/dynamic-link.h (VERSYMIDX): Likewise. + * elf/rtld.c (VALIDX): Likewise. + (ADDRIDX): Likewise. + * sysdeps/sparc/sparc32/dl-machine.h (VALIDX): Likewise. + * sysdeps/sparc/sparc64/dl-machine.h (VALIDX): Likewise. + * sysdeps/x86_64/dl-tlsdesc.h (ADDRIDX): Likewise. + * sysdeps/generic/ldsodefs.h (VERSYMIDX): New macro. + (VALIDX): Likewise. + (ADDRIDX): Likewise. + +2012-09-28 Pino Toscano <toscano.pino@tiscali.it> + + * sysdeps/pthread/aio_fsync.c: Fix the file mode checking. + +2012-09-28 Dmitry V. Levin <ldv@altlinux.org> + + [BZ #11438] + * sysdeps/posix/getaddrinfo.c (default_scopes): Map RFC 1918 addresses + to global scope. + * posix/tst-rfc3484.c: Verify 10/8, 172.16/12 and 196.128/16 + addresses are in the same scope as 192.0.2/24. + * posix/gai.conf: Document new scope table defaults. + +2012-09-28 Siddhesh Poyarekar <siddhesh@redhat.com> + + [BZ #5298] + * libio/fileops.c (_IO_new_file_seekoff): Don't flush buffer + for ftell. Compute offsets from write pointers instead. + * libio/wfileops.c (_IO_wfile_seekoff): Likewise. + +2012-09-28 Siddhesh Poyarekar <siddhesh@redhat.com> + + [BZ #14543] + * libio/Makefile (tests): New test case tst-fseek. + * libio/tst-fseek.c: New test case to verify that fseek/ftell + combination works in wide mode. + * libio/wfileops.c (_IO_wfile_seekoff): Adjust internal buffer + state when the external buffer state changes. + +2012-09-27 David S. Miller <davem@davemloft.net> + + [BZ #14376] + * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Do not + pass reloc->r_addend in as the 'high' argument to + sparc64_fixup_plt when handling R_SPARC_JMP_IREL relocations. + + * sysdeps/sparc/fpu/libm-test-ulps: Update. + +2012-09-28 Pino Toscano <toscano.pino@tiscali.it> + + * rt/tst-aio2.c: Include <pthread.h>. + * rt/tst-aio3.c: Likewise. + +2012-09-27 Steve Ellcey <sellcey@mips.com> + + * sysdeps/ieee754/ldbl-128/bits/huge_vall.h: Remove. + +2012-09-27 H.J. Lu <hongjiu.lu@intel.com> + + * sysdeps/x86_64/multiarch/strncmp-ssse3.S: Conditionalize + contents on [SHARED]. + +2012-09-26 Marek Polacek <polacek@redhat.com> + + [BZ #14530] + [BZ #13741] + * misc/sys/cdefs.h: Define __extern_inline and __extern_always_inline + for C++ and GCC <4.3 as well as for non GCC compilers. + +2012-09-26 Markus Trippelsdorf <markus@trippelsdorf.de> + + * sysdeps/x86_64/fpu/libm-test-ulps: Update. + +2012-09-25 Roland McGrath <roland@hack.frob.com> + + * Makefile.in (all, install): Declare with .PHONY. + Reported by Michael Hope <michael.hope@linaro.org>. + +2012-09-25 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com> + + * manual/platform.texi (PowerPC): Document __ppc_get_timebase_freq. + * sysdeps/powerpc/sys/platform/ppc.h: Include the operating + system header. + * sysdeps/unix/sysv/linux/powerpc/Makefile (sysdep_headers): + Likewise. + (sydep_routines): Add the new and the internal functions. + * sysdeps/unix/sysv/linux/powerpc/bits/ppc.h: New file. + * sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions + (GLIBC_2.17): Add the new function. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist + (GLIBC_2.17): Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions + (GLIBC_2.17): Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist + (GLIBC_2.17): Likewise. + * sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c: New file. + +2012-09-25 Alan Modra <amodra@gmail.com> + + * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once): + Add release barrier before setting once_control to say + initialisation is done. Add hints on lwarx. Use macro in + place of isync. + (clear_once_control): Add release barrier. + +2012-09-25 Joseph Myers <joseph@codesourcery.com> + + [BZ #13629] + * math/s_clog.c (__clog): Handle more values close to |z| = 1 + specially. + * math/s_clog10.c (__clog10): Likewise. + * math/s_clog10f.c (__clog10f): Likewise. + * math/s_clog10l.c (__clog10l): Likewise. + * math/s_clogf.c (__clogf): Likewise. + * math/s_clogl.c (__clogl): Likewise. + * math/Makefile (libm-calls): Add x2y2m1. + * sysdeps/generic/math_private.h (__x2y2m1f): Declare. + (__x2y2m1): Likewise. + (__x2y2m1l): Likewise. + * sysdeps/ieee754/dbl-64/x2y2m1.c: New file. + * sysdeps/ieee754/dbl-64/x2y2m1f.c: Likewise. + * sysdeps/ieee754/ldbl-128/x2y2m1l.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c: Likewise. + * sysdeps/ieee754/ldbl-96/x2y2m1.c: Likewise. + * sysdeps/ieee754/ldbl-96/x2y2m1l.c: Likewise. + * math/libm-test.inc (clog_test, clog10_test): Add more tests. + * sysdeps/i386/fpu/libm-test-ulps: Update. + * sysdeps/x86_64/fpu/libm-test-ulps: Likewise. + + [BZ #14621] + * posix/glob.c (next_brace_sub): Use size_t instead of unsigned + int as type of variable DEPTH. + (glob): Use size_t instead of int as type of variables NEWCOUNT + and OLD_PATHC. + +2012-09-25 Liubov Dmitrieva <liubov.dmitrieva@gmail.com> + + * sysdeps/i386/i686/fpu/multiarch/Makefile (sysdep_routines): + Add s_sincosf-sse2. + * sysdeps/i386/i686/fpu/multiarch/s_sincosf.c: New file. + * sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S: New file. + * sysdeps/ieee754/flt-32/s_sincosf.c (SINCOSF, SINCOSF_FUNC): Add + macros for using routine as __sincosf_ia32. + Use macro for function declaration and weak_alias. + * sysdeps/i386/fpu/libm-test-ulps: Update. + + * sysdeps/x86_64/fpu/s_sincosf.S: New file. + * sysdeps/x86_64/fpu/libm-test-ulps: Update. + + * math/s_ccoshf.c (__ccoshf): Fix wrong usage of sincos for + subnormal argument. + * math/s_cexpf.c (__cexpf): Likewise. + * math/s_csinf.c (__csinf): Likewise. + * math/s_csinhf.c (__csinhf): Likewise. + * math/s_ctanf.c (__ctanf): Likewise. + * math/s_ctanhf.c (__ctanhf): Likewise. + * math/s_ccosh.c (__ccoshf): Likewise. + * math/s_cexp.c (__cexpl): Likewise. + * math/s_csin.c (__csin): Likewise. + * math/s_csinh.c (__csinh): Likewise. + * math/s_ctan.c (__ctan): Likewise. + * math/s_ctanh.c (ctanh): Likewise. + * math/s_ccoshl.c (__ccoshl): Likewise. + * math/s_cexpl.c (__cexpl): Likewise. + * math/s_csinl.c (__csinl): Likewise. + * math/s_csinhl.c (__csinhl): Likewise. + * math/s_ctanl.c (__ctanl): Likewise. + * math/s_ctanhl.c (__ctanhl): Likewise. + 2012-09-25 Joseph Myers <joseph@codesourcery.com> * libio/libio.h (_IO_size_t): Define to size_t, not _G_size_t. diff --git a/libc/Makeconfig b/libc/Makeconfig index d3b2cffe6..f380bb653 100644 --- a/libc/Makeconfig +++ b/libc/Makeconfig @@ -494,15 +494,14 @@ link-libc-tests = $(link-libc-before-gnulib) $(gnulib-tests) rpath-dirs = math elf dlfcn nss nis rt resolv crypt rpath-link = \ $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%))) -elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf) else -nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss) -resolvobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)resolv) link-libc = $(common-objpfx)libc.a $(otherlibs) $(gnulib) $(common-objpfx)libc.a $(gnulib) link-libc-tests = $(common-objpfx)libc.a $(otherlibs) $(gnulib-tests) $(common-objpfx)libc.a $(gnulib-tests) endif endif +elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf) + # Differences in the linkers on the various platforms. LDFLAGS-rpath-ORIGIN = -Wl,-rpath,'$$ORIGIN' LDFLAGS-soname-fname = -Wl,-soname,$(@F) diff --git a/libc/Makefile.in b/libc/Makefile.in index 1f5dc1cd7..d73a78f8e 100644 --- a/libc/Makefile.in +++ b/libc/Makefile.in @@ -3,6 +3,8 @@ srcdir = @srcdir@ # Uncomment the line below if you want to do parallel build. # PARALLELMFLAGS = -j 4 +.PHONY: all install + all .DEFAULT: $(MAKE) -r PARALLELMFLAGS="$(PARALLELMFLAGS)" -C $(srcdir) objdir=`pwd` $@ diff --git a/libc/Makerules b/libc/Makerules index 009e736aa..16db52461 100644 --- a/libc/Makerules +++ b/libc/Makerules @@ -1216,7 +1216,7 @@ ifeq ($(versioning),yes) mv -f $@T $@ %.dynsym: %.so - $(OBJDUMP) --dynamic-syms $< > $@T + LC_ALL=C $(OBJDUMP) --dynamic-syms $< > $@T mv -f $@T $@ vpath %.abilist $(+sysdep_dirs) @@ -9,12 +9,14 @@ Version 2.17 * The following bugs are resolved with this release: - 1349, 3479, 5044, 5400, 6778, 6808, 9685, 9914, 10014, 10038, 11607, - 13412, 13542, 13679, 13717, 13696, 13939, 13966, 14042, 14090, 14166, - 14150, 14151, 14154, 14157, 14166, 14173, 14195, 14237, 14252, 14283, - 14298, 14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14459, - 14476, 14505, 14510, 14516, 14518, 14519, 14532, 14538, 14544, 14545, - 14562, 14576, 14579, 14583, 14587. + 1349, 3479, 5044, 5298, 5400, 6530, 6778, 6808, 9685, 9914, 10014, 10038, + 10631, 11438, 11607, 13412, 13542, 13629, 13679, 13696, 13717, 13741, + 13939, 13966, 14042, 14090, 14150, 14151, 14154, 14157, 14166, 14173, + 14195, 14237, 14251, 14252, 14283, 14298, 14303, 14307, 14328, 14331, + 14336, 14337, 14347, 14349, 14376, 14417, 14459, 14476, 14477, 14505, + 14510, 14516, 14518, 14519, 14530, 14532, 14538, 14543, 14544, 14545, + 14557, 14562, 14568, 14576, 14579, 14583, 14587, 14621, 14638, 14645, + 14648, 14660, 14661. * Support for STT_GNU_IFUNC symbols added for s390 and s390x. Optimized versions of memcpy, memset, and memcmp added for System z10 and diff --git a/libc/aclocal.m4 b/libc/aclocal.m4 index 626e4369b..7ecdd6ba6 100644 --- a/libc/aclocal.m4 +++ b/libc/aclocal.m4 @@ -10,11 +10,19 @@ AC_PROVIDE([_AS_ECHO_N_PREPARE])dnl AC_PROVIDE([_AS_ECHO_PREPARE])dnl AC_PROVIDE([_AS_CR_PREPARE])dnl AC_PROVIDE([_AS_TR_SH_PREPARE])dnl +AC_PROVIDE([_AS_VAR_ARITH_PREPARE])dnl AC_PROVIDE([AC_PROG_INSTALL])dnl AC_PROVIDE([AC_PROG_CC])dnl AC_PROVIDE([AC_PROG_CPP])dnl AC_PROVIDE([_AS_PATH_SEPARATOR_PREPARE])dnl AC_PROVIDE([_AS_TEST_PREPARE])dnl +AC_PROVIDE([_AS_BASENAME_PREPARE])dnl +AC_PROVIDE([_AS_ME_PREPARE])dnl +AC_PROVIDE([_AS_LINENO_PREPARE])dnl +AC_PROVIDE([AS_SHELL_FN_as_fn_set_status])dnl +AC_PROVIDE([AS_SHELL_FN_as_fn_exit])dnl +AC_PROVIDE([AS_SHELL_FN_as_fn_arith])dnl +AC_PROVIDE([AS_SHELL_FN_ac_fn_c_try_compile])dnl define([AS_MESSAGE_LOG_FD],5)dnl define([AS_MESSAGE_FD],6)dnl dnl Ripped out of AS_INIT, which does more cruft we do not want. diff --git a/libc/bits/types.h b/libc/bits/types.h index 041ace631..51ef89b7a 100644 --- a/libc/bits/types.h +++ b/libc/bits/types.h @@ -150,7 +150,6 @@ __STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */ __STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */ __STD_TYPE __DADDR_T_TYPE __daddr_t; /* The type of a disk address. */ -__STD_TYPE __SWBLK_T_TYPE __swblk_t; /* Type of a swap block maybe? */ __STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */ /* Clock ID used in clock and timer functions. */ diff --git a/libc/bits/typesizes.h b/libc/bits/typesizes.h index c3debd0dd..ac18c8199 100644 --- a/libc/bits/typesizes.h +++ b/libc/bits/typesizes.h @@ -51,7 +51,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SLONGWORD_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE void * diff --git a/libc/config.h.in b/libc/config.h.in index 68b399927..7d824eee6 100644 --- a/libc/config.h.in +++ b/libc/config.h.in @@ -183,6 +183,9 @@ /* Define if library functions should try to contact the nscd daemon. */ #undef USE_NSCD +/* Define if the dynamic linker should consult an ld.so.cache file. */ +#undef USE_LDCONFIG + /* */ diff --git a/libc/configure b/libc/configure index 6e30b1701..09a82e016 100755 --- a/libc/configure +++ b/libc/configure @@ -7588,6 +7588,10 @@ fi +if test x$use_ldconfig = xyes; then + $as_echo "#define USE_LDCONFIG 1" >>confdefs.h + +fi diff --git a/libc/configure.in b/libc/configure.in index bf2cb5412..f9f908ad6 100644 --- a/libc/configure.in +++ b/libc/configure.in @@ -2189,6 +2189,9 @@ AC_SUBST(libc_cv_cc_nofma) AC_SUBST(libc_cv_as_i686) AC_SUBST(libc_cv_sparc_as_vis3) +if test x$use_ldconfig = xyes; then + AC_DEFINE(USE_LDCONFIG) +fi AC_SUBST(use_ldconfig) AC_SUBST(ldd_rewrite_script) diff --git a/libc/csu/init-first.c b/libc/csu/init-first.c index 050959dcb..0cfabbce2 100644 --- a/libc/csu/init-first.c +++ b/libc/csu/init-first.c @@ -1,4 +1,4 @@ -/* Initialization code run first thing by the ELF startup code. Stub version. +/* Initialization code run first thing by the ELF startup code. Common version Copyright (C) 1995-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,40 +17,76 @@ <http://www.gnu.org/licenses/>. */ #include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> #include <unistd.h> +#include <sysdep.h> +#include <fpu_control.h> +#include <sys/param.h> #include <sys/types.h> +#include <libc-internal.h> + +#include <ldsodefs.h> /* Set nonzero if we have to be prepared for more then one libc being used in the process. Safe assumption if initializer never runs. */ int __libc_multiple_libcs attribute_hidden = 1; -extern void __libc_init (int, char **, char **); -#ifdef USE_NONOPTION_FLAGS -extern void __getopt_clean_environment (char **); -#endif +/* Remember the command line argument and enviroment contents for + later calls of initializers for dynamic libraries. */ +int __libc_argc attribute_hidden; +char **__libc_argv attribute_hidden; + -#ifdef SHARED void -__libc_init_first (void) +__libc_init_first (int argc, char **argv, char **envp) { +#ifdef SHARED + /* For DSOs we do not need __libc_init_first but instead _init. */ } + +void +attribute_hidden +_init (int argc, char **argv, char **envp) +{ +#endif +#ifdef USE_NONOPTION_FLAGS + extern void __getopt_clean_environment (char **); #endif + __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; + + /* Make sure we don't initialize twice. */ + if (!__libc_multiple_libcs) + { + /* Set the FPU control word to the proper default value if the + kernel would use a different value. (In a static program we + don't have this information.) */ #ifdef SHARED -/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT - pointer in the dynamic section based solely on that. It is convention - for this function to be in the `.init' section, but the symbol name is - the only thing that really matters!! */ -void _init -#else -void __libc_init_first + if (__fpu_control != GLRO(dl_fpu_control)) #endif -(int argc, char *arg0, ...) -{ - char **argv = &arg0, **envp = &argv[argc + 1]; + __setfpucw (__fpu_control); + } + /* Save the command-line arguments. */ + __libc_argc = argc; + __libc_argv = argv; __environ = envp; - __libc_init (argc, argv, envp); + +#ifndef SHARED + __libc_init_secure (); + + /* First the initialization which normally would be done by the + dynamic linker. */ + _dl_non_dynamic_init (); +#endif + +#ifdef VDSO_SETUP + VDSO_SETUP (); +#endif + + __init_misc (argc, argv, envp); #ifdef USE_NONOPTION_FLAGS /* This is a hack to make the special getopt in GNU libc working. */ @@ -59,4 +95,21 @@ void __libc_init_first /* Initialize ctype data. */ __ctype_init (); + +#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS + __libc_global_ctors (); +#endif +} + +/* This function is defined here so that if this file ever gets into + ld.so we will get a link error. Having this file silently included + in ld.so causes disaster, because the _init definition above will + cause ld.so to gain an init function, which is not a cool thing. */ + +extern void _dl_start (void) __attribute__ ((noreturn)); + +void +_dl_start (void) +{ + abort (); } diff --git a/libc/dlfcn/dlerror.c b/libc/dlfcn/dlerror.c index 8138cc278..c30b4f1d3 100644 --- a/libc/dlfcn/dlerror.c +++ b/libc/dlfcn/dlerror.c @@ -1,5 +1,5 @@ /* Return error detail for failing <dlfcn.h> functions. - Copyright (C) 1995-2000,2002,2003,2004,2005 Free Software Foundation, Inc. + Copyright (C) 1995-2012 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 @@ -190,11 +190,14 @@ check_free (struct dl_action_result *rec) { /* We can free the string only if the allocation happened in the C library used by the dynamic linker. This means, it is - always the C library in the base namespave. */ + always the C library in the base namespace. When we're statically + linked, the dynamic linker is part of the program and so always + uses the same C library we use here. */ +#ifdef SHARED struct link_map *map = NULL; Dl_info info; - if (_dl_addr (check_free, &info, &map, NULL) != 0 - && map != NULL && map->l_ns == 0) + if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0) +#endif free ((char *) rec->errstring); } } diff --git a/libc/elf/Makefile b/libc/elf/Makefile index b3b950be4..276581812 100644 --- a/libc/elf/Makefile +++ b/libc/elf/Makefile @@ -19,6 +19,8 @@ subdir := elf +include ../Makeconfig + headers = elf.h bits/elfclass.h link.h bits/link.h routines = $(dl-routines) dl-support dl-iteratephdr \ dl-addr enbl-secure dl-profstub \ @@ -26,10 +28,13 @@ routines = $(dl-routines) dl-support dl-iteratephdr \ # The core dynamic linking functions are in libc for the static and # profiled libraries. -dl-routines = $(addprefix dl-,load cache lookup object reloc deps \ +dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \ runtime error init fini debug misc \ version profile conflict tls origin scope \ execstack caller open close trampoline) +ifeq (yes,$(use-ldconfig)) +dl-routines += dl-cache +endif all-dl-routines = $(dl-routines) $(sysdep-dl-routines) # But they are absent from the shared libc, because that code is in ld.so. elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ @@ -45,8 +50,6 @@ CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-dl-iterate-phdr.c = $(uses-callbacks) -include ../Makeconfig - ifeq ($(unwind-find-fde),yes) routines += unwind-dw2-fde-glibc shared-only-routines += unwind-dw2-fde-glibc diff --git a/libc/elf/dl-hwcaps.c b/libc/elf/dl-hwcaps.c new file mode 100644 index 000000000..d911548f2 --- /dev/null +++ b/libc/elf/dl-hwcaps.c @@ -0,0 +1,279 @@ +/* Hardware capability support for run-time dynamic loader. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <elf.h> +#include <errno.h> +#include <libintl.h> +#include <unistd.h> +#include <ldsodefs.h> + +#include <dl-procinfo.h> + +#ifdef _DL_FIRST_PLATFORM +# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT) +#else +# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT +#endif + +/* Return an array of useful/necessary hardware capability names. */ +const struct r_strlenpair * +internal_function +_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, + size_t *max_capstrlen) +{ + /* Determine how many important bits are set. */ + uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask); + size_t cnt = platform != NULL; + size_t n, m; + size_t total; + struct r_strlenpair *temp; + struct r_strlenpair *result; + struct r_strlenpair *rp; + char *cp; + + /* Count the number of bits set in the masked value. */ + for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n) + if ((masked & (1ULL << n)) != 0) + ++cnt; + +#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO + /* The system-supplied DSO can contain a note of type 2, vendor "GNU". + This gives us a list of names to treat as fake hwcap bits. */ + + const char *dsocaps = NULL; + size_t dsocapslen = 0; + if (GLRO(dl_sysinfo_map) != NULL) + { + const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr; + const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum; + for (uint_fast16_t i = 0; i < phnum; ++i) + if (phdr[i].p_type == PT_NOTE) + { + const ElfW(Addr) start = (phdr[i].p_vaddr + + GLRO(dl_sysinfo_map)->l_addr); + const struct + { + ElfW(Word) vendorlen; + ElfW(Word) datalen; + ElfW(Word) type; + } *note = (const void *) start; + while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz) + { +#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word))) + if (note->type == NT_GNU_HWCAP + && note->vendorlen == sizeof "GNU" + && !memcmp ((note + 1), "GNU", sizeof "GNU") + && note->datalen > 2 * sizeof (ElfW(Word)) + 2) + { + const ElfW(Word) *p = ((const void *) (note + 1) + + ROUND (sizeof "GNU")); + cnt += *p++; + ++p; /* Skip mask word. */ + dsocaps = (const char *) p; + dsocapslen = note->datalen - sizeof *p * 2; + break; + } + note = ((const void *) (note + 1) + + ROUND (note->vendorlen) + ROUND (note->datalen)); +#undef ROUND + } + if (dsocaps != NULL) + break; + } + } +#endif + + /* For TLS enabled builds always add 'tls'. */ + ++cnt; + + /* Create temporary data structure to generate result table. */ + temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp)); + m = 0; +#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO + if (dsocaps != NULL) + { + const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1]; + GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA; + /* Note that we add the dsocaps to the set already chosen by the + LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT). + So there is no way to request ignoring an OS-supplied dsocap + string and bit like you can ignore an OS-supplied HWCAP bit. */ + GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA; + size_t len; + for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1) + { + uint_fast8_t bit = *p++; + len = strlen (p); + + /* Skip entries that are not enabled in the mask word. */ + if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1)) + { + temp[m].str = p; + temp[m].len = len; + ++m; + } + else + --cnt; + } + } +#endif + for (n = 0; masked != 0; ++n) + if ((masked & (1ULL << n)) != 0) + { + temp[m].str = _dl_hwcap_string (n); + temp[m].len = strlen (temp[m].str); + masked ^= 1ULL << n; + ++m; + } + if (platform != NULL) + { + temp[m].str = platform; + temp[m].len = platform_len; + ++m; + } + + temp[m].str = "tls"; + temp[m].len = 3; + ++m; + + assert (m == cnt); + + /* Determine the total size of all strings together. */ + if (cnt == 1) + total = temp[0].len + 1; + else + { + total = temp[0].len + temp[cnt - 1].len + 2; + if (cnt > 2) + { + total <<= 1; + for (n = 1; n + 1 < cnt; ++n) + total += temp[n].len + 1; + if (cnt > 3 + && (cnt >= sizeof (size_t) * 8 + || total + (sizeof (*result) << 3) + >= (1UL << (sizeof (size_t) * 8 - cnt + 3)))) + _dl_signal_error (ENOMEM, NULL, NULL, + N_("cannot create capability list")); + + total <<= cnt - 3; + } + } + + /* The result structure: we use a very compressed way to store the + various combinations of capability names. */ + *sz = 1 << cnt; + result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total); + if (result == NULL) + _dl_signal_error (ENOMEM, NULL, NULL, + N_("cannot create capability list")); + + if (cnt == 1) + { + result[0].str = (char *) (result + *sz); + result[0].len = temp[0].len + 1; + result[1].str = (char *) (result + *sz); + result[1].len = 0; + cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len); + *cp = '/'; + *sz = 2; + *max_capstrlen = result[0].len; + + return result; + } + + /* Fill in the information. This follows the following scheme + (indeces from TEMP for four strings): + entry #0: 0, 1, 2, 3 binary: 1111 + #1: 0, 1, 3 1101 + #2: 0, 2, 3 1011 + #3: 0, 3 1001 + This allows the representation of all possible combinations of + capability names in the string. First generate the strings. */ + result[1].str = result[0].str = cp = (char *) (result + *sz); +#define add(idx) \ + cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1); + if (cnt == 2) + { + add (1); + add (0); + } + else + { + n = 1 << (cnt - 1); + do + { + n -= 2; + + /* We always add the last string. */ + add (cnt - 1); + + /* Add the strings which have the bit set in N. */ + for (m = cnt - 2; m > 0; --m) + if ((n & (1 << m)) != 0) + add (m); + + /* Always add the first string. */ + add (0); + } + while (n != 0); + } +#undef add + + /* Now we are ready to install the string pointers and length. */ + for (n = 0; n < (1UL << cnt); ++n) + result[n].len = 0; + n = cnt; + do + { + size_t mask = 1 << --n; + + rp = result; + for (m = 1 << cnt; m > 0; ++rp) + if ((--m & mask) != 0) + rp->len += temp[n].len + 1; + } + while (n != 0); + + /* The first half of the strings all include the first string. */ + n = (1 << cnt) - 2; + rp = &result[2]; + while (n != (1UL << (cnt - 1))) + { + if ((--n & 1) != 0) + rp[0].str = rp[-2].str + rp[-2].len; + else + rp[0].str = rp[-1].str; + ++rp; + } + + /* The second half starts right after the first part of the string of + the corresponding entry in the first half. */ + do + { + rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1; + ++rp; + } + while (--n != 0); + + /* The maximum string length. */ + *max_capstrlen = result[0].len; + + return result; +} diff --git a/libc/elf/dl-load.c b/libc/elf/dl-load.c index 4d708bc5d..524e7369e 100644 --- a/libc/elf/dl-load.c +++ b/libc/elf/dl-load.c @@ -1090,7 +1090,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, struct loadcmd { ElfW(Addr) mapstart, mapend, dataend, allocend; - off_t mapoff; + ElfW(Off) mapoff; int prot; } loadcmds[l->l_phnum], *c; size_t nloadcmds = 0; @@ -1347,7 +1347,7 @@ cannot allocate TLS data structures for initial thread"); l->l_text_end = l->l_addr + c->mapend; if (l->l_phdr == 0 - && (ElfW(Off)) c->mapoff <= header->e_phoff + && c->mapoff <= header->e_phoff && ((size_t) (c->mapend - c->mapstart + c->mapoff) >= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr)))) /* Found the program header in this segment. */ @@ -2201,6 +2201,7 @@ _dl_map_object (struct link_map *loader, const char *name, &loader->l_runpath_dirs, &realname, &fb, loader, LA_SER_RUNPATH, &found_other_class); +#ifdef USE_LDCONFIG if (fd == -1 && (__builtin_expect (! (mode & __RTLD_SECURE), 1) || ! INTUSE(__libc_enable_secure)) @@ -2212,22 +2213,22 @@ _dl_map_object (struct link_map *loader, const char *name, if (cached != NULL) { -#ifdef SHARED +# ifdef SHARED // XXX Correct to unconditionally default to namespace 0? l = (loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded ?: &GL(dl_rtld_map)); -#else +# else l = loader; -#endif +# endif /* If the loader has the DF_1_NODEFLIB flag set we must not use a cache entry from any of these directories. */ if ( -#ifndef SHARED +# ifndef SHARED /* 'l' is always != NULL for dynamically linked objects. */ l != NULL && -#endif +# endif __builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0)) { const char *dirp = system_dirs; @@ -2265,6 +2266,7 @@ _dl_map_object (struct link_map *loader, const char *name, } } } +#endif /* Finally, try the default path. */ if (fd == -1 diff --git a/libc/elf/dl-open.c b/libc/elf/dl-open.c index 903bdf13f..703218b0c 100644 --- a/libc/elf/dl-open.c +++ b/libc/elf/dl-open.c @@ -654,8 +654,8 @@ no more namespaces available for dlmopen()")); int errcode = _dl_catch_error (&objname, &errstring, &malloced, dl_open_worker, &args); -#ifndef MAP_COPY - /* We must munmap() the cache file. */ +#if defined USE_LDCONFIG && !defined MAP_COPY + /* We must unmap the cache file. */ _dl_unload_cache (); #endif diff --git a/libc/elf/dl-runtime.c b/libc/elf/dl-runtime.c index fdaa364c6..2e02a218e 100644 --- a/libc/elf/dl-runtime.c +++ b/libc/elf/dl-runtime.c @@ -36,10 +36,6 @@ # define PLTREL ElfW(Rel) #endif -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif - /* The fixup functions might have need special attributes. If none are provided define the macro as empty. */ #ifndef ARCH_FIXUP_ATTRIBUTE diff --git a/libc/elf/dl-support.c b/libc/elf/dl-support.c index dff9aa074..a74cf636d 100644 --- a/libc/elf/dl-support.c +++ b/libc/elf/dl-support.c @@ -164,6 +164,11 @@ uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT; #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO /* Address of the ELF headers in the vsyscall page. */ const ElfW(Ehdr) *_dl_sysinfo_dso; + +struct link_map *_dl_sysinfo_map; + +# include "get-dynamic-info.h" +# include "setup-vdso.h" #endif /* During the program run we must not modify the global data of @@ -269,6 +274,10 @@ _dl_non_dynamic_init (void) _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; + /* Set up the data structures for the system-supplied DSO early, + so they can influence _dl_init_paths. */ + setup_vdso (NULL, NULL); + /* Initialize the data structures for the search paths for shared objects. */ _dl_init_paths (getenv ("LD_LIBRARY_PATH")); @@ -329,23 +338,6 @@ _dl_non_dynamic_init (void) } } - -const struct r_strlenpair * -internal_function -_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, - size_t *max_capstrlen) -{ - static struct r_strlenpair result; - static char buf[1]; - - result.str = buf; /* Does not really matter. */ - result.len = 0; - - *sz = 1; - return &result; -} - - #ifdef DL_SYSINFO_IMPLEMENTATION DL_SYSINFO_IMPLEMENTATION #endif diff --git a/libc/elf/dl-sysdep.c b/libc/elf/dl-sysdep.c index 7d2283910..65a90469c 100644 --- a/libc/elf/dl-sysdep.c +++ b/libc/elf/dl-sysdep.c @@ -1,6 +1,5 @@ /* Operating system support for run-time dynamic linker. Generic Unix version. - Copyright (C) 1995-1998,2000-2010,2012 - Free Software Foundation, Inc. + Copyright (C) 1995-2012 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 @@ -17,6 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* We conditionalize the whole of this file rather than simply eliding it + from the static build, because other sysdeps/ versions of this file + might define things needed by a static build. */ + +#ifdef SHARED + #include <assert.h> #include <elf.h> #include <errno.h> @@ -39,12 +44,6 @@ #include <hp-timing.h> #include <tls.h> -#ifdef _DL_FIRST_PLATFORM -# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT) -#else -# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT -#endif - extern char **_environ attribute_hidden; extern char _end[] attribute_hidden; @@ -345,250 +344,4 @@ _dl_show_auxv (void) } } - -/* Return an array of useful/necessary hardware capability names. */ -const struct r_strlenpair * -internal_function -_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, - size_t *max_capstrlen) -{ - /* Determine how many important bits are set. */ - uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask); - size_t cnt = platform != NULL; - size_t n, m; - size_t total; - struct r_strlenpair *temp; - struct r_strlenpair *result; - struct r_strlenpair *rp; - char *cp; - - /* Count the number of bits set in the masked value. */ - for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n) - if ((masked & (1ULL << n)) != 0) - ++cnt; - -#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED - /* The system-supplied DSO can contain a note of type 2, vendor "GNU". - This gives us a list of names to treat as fake hwcap bits. */ - - const char *dsocaps = NULL; - size_t dsocapslen = 0; - if (GLRO(dl_sysinfo_map) != NULL) - { - const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr; - const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum; - for (uint_fast16_t i = 0; i < phnum; ++i) - if (phdr[i].p_type == PT_NOTE) - { - const ElfW(Addr) start = (phdr[i].p_vaddr - + GLRO(dl_sysinfo_map)->l_addr); - const struct - { - ElfW(Word) vendorlen; - ElfW(Word) datalen; - ElfW(Word) type; - } *note = (const void *) start; - while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz) - { -#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word))) - if (note->type == NT_GNU_HWCAP - && note->vendorlen == sizeof "GNU" - && !memcmp ((note + 1), "GNU", sizeof "GNU") - && note->datalen > 2 * sizeof (ElfW(Word)) + 2) - { - const ElfW(Word) *p = ((const void *) (note + 1) - + ROUND (sizeof "GNU")); - cnt += *p++; - ++p; /* Skip mask word. */ - dsocaps = (const char *) p; - dsocapslen = note->datalen - sizeof *p * 2; - break; - } - note = ((const void *) (note + 1) - + ROUND (note->vendorlen) + ROUND (note->datalen)); -#undef ROUND - } - if (dsocaps != NULL) - break; - } - } -#endif - - /* For TLS enabled builds always add 'tls'. */ - ++cnt; - - /* Create temporary data structure to generate result table. */ - temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp)); - m = 0; -#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED - if (dsocaps != NULL) - { - const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1]; - GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA; - /* Note that we add the dsocaps to the set already chosen by the - LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT). - So there is no way to request ignoring an OS-supplied dsocap - string and bit like you can ignore an OS-supplied HWCAP bit. */ - GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA; - size_t len; - for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1) - { - uint_fast8_t bit = *p++; - len = strlen (p); - - /* Skip entries that are not enabled in the mask word. */ - if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1)) - { - temp[m].str = p; - temp[m].len = len; - ++m; - } - else - --cnt; - } - } #endif - for (n = 0; masked != 0; ++n) - if ((masked & (1ULL << n)) != 0) - { - temp[m].str = _dl_hwcap_string (n); - temp[m].len = strlen (temp[m].str); - masked ^= 1ULL << n; - ++m; - } - if (platform != NULL) - { - temp[m].str = platform; - temp[m].len = platform_len; - ++m; - } - - temp[m].str = "tls"; - temp[m].len = 3; - ++m; - - assert (m == cnt); - - /* Determine the total size of all strings together. */ - if (cnt == 1) - total = temp[0].len + 1; - else - { - total = temp[0].len + temp[cnt - 1].len + 2; - if (cnt > 2) - { - total <<= 1; - for (n = 1; n + 1 < cnt; ++n) - total += temp[n].len + 1; - if (cnt > 3 - && (cnt >= sizeof (size_t) * 8 - || total + (sizeof (*result) << 3) - >= (1UL << (sizeof (size_t) * 8 - cnt + 3)))) - _dl_signal_error (ENOMEM, NULL, NULL, - N_("cannot create capability list")); - - total <<= cnt - 3; - } - } - - /* The result structure: we use a very compressed way to store the - various combinations of capability names. */ - *sz = 1 << cnt; - result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total); - if (result == NULL) - _dl_signal_error (ENOMEM, NULL, NULL, - N_("cannot create capability list")); - - if (cnt == 1) - { - result[0].str = (char *) (result + *sz); - result[0].len = temp[0].len + 1; - result[1].str = (char *) (result + *sz); - result[1].len = 0; - cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len); - *cp = '/'; - *sz = 2; - *max_capstrlen = result[0].len; - - return result; - } - - /* Fill in the information. This follows the following scheme - (indeces from TEMP for four strings): - entry #0: 0, 1, 2, 3 binary: 1111 - #1: 0, 1, 3 1101 - #2: 0, 2, 3 1011 - #3: 0, 3 1001 - This allows the representation of all possible combinations of - capability names in the string. First generate the strings. */ - result[1].str = result[0].str = cp = (char *) (result + *sz); -#define add(idx) \ - cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1); - if (cnt == 2) - { - add (1); - add (0); - } - else - { - n = 1 << (cnt - 1); - do - { - n -= 2; - - /* We always add the last string. */ - add (cnt - 1); - - /* Add the strings which have the bit set in N. */ - for (m = cnt - 2; m > 0; --m) - if ((n & (1 << m)) != 0) - add (m); - - /* Always add the first string. */ - add (0); - } - while (n != 0); - } -#undef add - - /* Now we are ready to install the string pointers and length. */ - for (n = 0; n < (1UL << cnt); ++n) - result[n].len = 0; - n = cnt; - do - { - size_t mask = 1 << --n; - - rp = result; - for (m = 1 << cnt; m > 0; ++rp) - if ((--m & mask) != 0) - rp->len += temp[n].len + 1; - } - while (n != 0); - - /* The first half of the strings all include the first string. */ - n = (1 << cnt) - 2; - rp = &result[2]; - while (n != (1UL << (cnt - 1))) - { - if ((--n & 1) != 0) - rp[0].str = rp[-2].str + rp[-2].len; - else - rp[0].str = rp[-1].str; - ++rp; - } - - /* The second half starts right after the first part of the string of - the corresponding entry in the first half. */ - do - { - rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1; - ++rp; - } - while (--n != 0); - - /* The maximum string length. */ - *max_capstrlen = result[0].len; - - return result; -} diff --git a/libc/elf/dl-version.c b/libc/elf/dl-version.c index 047db2f82..269c0aadf 100644 --- a/libc/elf/dl-version.c +++ b/libc/elf/dl-version.c @@ -28,11 +28,6 @@ #include <assert.h> -#ifndef VERSYMIDX -# define VERSYMIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) -#endif - - #define make_string(string, rest...) \ ({ \ const char *all[] = { string, ## rest }; \ diff --git a/libc/elf/do-rel.h b/libc/elf/do-rel.h index 1138ca4bd..cfb9a512f 100644 --- a/libc/elf/do-rel.h +++ b/libc/elf/do-rel.h @@ -32,14 +32,6 @@ (void *) (l_addr + relative->r_offset)) #endif -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif -#ifndef VALIDX -# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALTAGIDX (tag)) -#endif - /* Perform the relocations in MAP on the running program image as specified by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT relocations; they should be set up to call _dl_runtime_resolve, rather diff --git a/libc/elf/dynamic-link.h b/libc/elf/dynamic-link.h index 44f53b3c7..ad30d23a7 100644 --- a/libc/elf/dynamic-link.h +++ b/libc/elf/dynamic-link.h @@ -42,7 +42,6 @@ int internal_function _dl_try_allocate_static_tls (struct link_map *map); #include <elf.h> -#include <assert.h> #ifdef RESOLVE_MAP /* We pass reloc_addr as a pointer to void, as opposed to a pointer to @@ -88,153 +87,7 @@ elf_machine_lazy_rel (struct link_map *map, #include <dl-machine.h> -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif - - -/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ -#ifndef RESOLVE_MAP -static -#else -auto -#endif -inline void __attribute__ ((unused, always_inline)) -elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) -{ - ElfW(Dyn) *dyn = l->l_ld; - ElfW(Dyn) **info; -#if __ELF_NATIVE_CLASS == 32 - typedef Elf32_Word d_tag_utype; -#elif __ELF_NATIVE_CLASS == 64 - typedef Elf64_Xword d_tag_utype; -#endif - -#ifndef RTLD_BOOTSTRAP - if (dyn == NULL) - return; -#endif - - info = l->l_info; - - while (dyn->d_tag != DT_NULL) - { - if ((d_tag_utype) dyn->d_tag < DT_NUM) - info[dyn->d_tag] = dyn; - else if (dyn->d_tag >= DT_LOPROC && - dyn->d_tag < DT_LOPROC + DT_THISPROCNUM) - info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; - else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) - info[VERSYMIDX (dyn->d_tag)] = dyn; - else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) - info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM - + DT_VERSIONTAGNUM] = dyn; - else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) - info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM - + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn; - else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) - info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM - + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; - ++dyn; - } - -#define DL_RO_DYN_TEMP_CNT 8 - -#ifndef DL_RO_DYN_SECTION - /* Don't adjust .dynamic unnecessarily. */ - if (l->l_addr != 0) - { - ElfW(Addr) l_addr = l->l_addr; - int cnt = 0; - -# define ADJUST_DYN_INFO(tag) \ - do \ - if (info[tag] != NULL) \ - { \ - if (temp) \ - { \ - temp[cnt].d_tag = info[tag]->d_tag; \ - temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \ - info[tag] = temp + cnt++; \ - } \ - else \ - info[tag]->d_un.d_ptr += l_addr; \ - } \ - while (0) - - ADJUST_DYN_INFO (DT_HASH); - ADJUST_DYN_INFO (DT_PLTGOT); - ADJUST_DYN_INFO (DT_STRTAB); - ADJUST_DYN_INFO (DT_SYMTAB); -# if ! ELF_MACHINE_NO_RELA - ADJUST_DYN_INFO (DT_RELA); -# endif -# if ! ELF_MACHINE_NO_REL - ADJUST_DYN_INFO (DT_REL); -# endif - ADJUST_DYN_INFO (DT_JMPREL); - ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); - ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM - + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM); -# undef ADJUST_DYN_INFO - assert (cnt <= DL_RO_DYN_TEMP_CNT); - } -#endif - if (info[DT_PLTREL] != NULL) - { -#if ELF_MACHINE_NO_RELA - assert (info[DT_PLTREL]->d_un.d_val == DT_REL); -#elif ELF_MACHINE_NO_REL - assert (info[DT_PLTREL]->d_un.d_val == DT_RELA); -#else - assert (info[DT_PLTREL]->d_un.d_val == DT_REL - || info[DT_PLTREL]->d_un.d_val == DT_RELA); -#endif - } -#if ! ELF_MACHINE_NO_RELA - if (info[DT_RELA] != NULL) - assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela))); -# endif -# if ! ELF_MACHINE_NO_REL - if (info[DT_REL] != NULL) - assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); -#endif -#ifdef RTLD_BOOTSTRAP - /* Only the bind now flags are allowed. */ - assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL - || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); - assert (info[DT_FLAGS] == NULL - || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); - /* Flags must not be set for ld.so. */ - assert (info[DT_RUNPATH] == NULL); - assert (info[DT_RPATH] == NULL); -#else - if (info[DT_FLAGS] != NULL) - { - /* Flags are used. Translate to the old form where available. - Since these l_info entries are only tested for NULL pointers it - is ok if they point to the DT_FLAGS entry. */ - l->l_flags = info[DT_FLAGS]->d_un.d_val; - - if (l->l_flags & DF_SYMBOLIC) - info[DT_SYMBOLIC] = info[DT_FLAGS]; - if (l->l_flags & DF_TEXTREL) - info[DT_TEXTREL] = info[DT_FLAGS]; - if (l->l_flags & DF_BIND_NOW) - info[DT_BIND_NOW] = info[DT_FLAGS]; - } - if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) - { - l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; - - if (l->l_flags_1 & DF_1_NOW) - info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)]; - } - if (info[DT_RUNPATH] != NULL) - /* If both RUNPATH and RPATH are given, the latter is ignored. */ - info[DT_RPATH] = NULL; -#endif -} +#include "get-dynamic-info.h" #ifdef RESOLVE_MAP diff --git a/libc/elf/get-dynamic-info.h b/libc/elf/get-dynamic-info.h new file mode 100644 index 000000000..ffac75f63 --- /dev/null +++ b/libc/elf/get-dynamic-info.h @@ -0,0 +1,161 @@ +/* Read the dynamic section at DYN and fill in INFO with indices DT_*. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> + +#ifndef RESOLVE_MAP +static +#else +auto +#endif +inline void __attribute__ ((unused, always_inline)) +elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) +{ + ElfW(Dyn) *dyn = l->l_ld; + ElfW(Dyn) **info; +#if __ELF_NATIVE_CLASS == 32 + typedef Elf32_Word d_tag_utype; +#elif __ELF_NATIVE_CLASS == 64 + typedef Elf64_Xword d_tag_utype; +#endif + +#ifndef RTLD_BOOTSTRAP + if (dyn == NULL) + return; +#endif + + info = l->l_info; + + while (dyn->d_tag != DT_NULL) + { + if ((d_tag_utype) dyn->d_tag < DT_NUM) + info[dyn->d_tag] = dyn; + else if (dyn->d_tag >= DT_LOPROC && + dyn->d_tag < DT_LOPROC + DT_THISPROCNUM) + info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; + else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) + info[VERSYMIDX (dyn->d_tag)] = dyn; + else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) + info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + + DT_VERSIONTAGNUM] = dyn; + else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) + info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn; + else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) + info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; + ++dyn; + } + +#define DL_RO_DYN_TEMP_CNT 8 + +#ifndef DL_RO_DYN_SECTION + /* Don't adjust .dynamic unnecessarily. */ + if (l->l_addr != 0) + { + ElfW(Addr) l_addr = l->l_addr; + int cnt = 0; + +# define ADJUST_DYN_INFO(tag) \ + do \ + if (info[tag] != NULL) \ + { \ + if (temp) \ + { \ + temp[cnt].d_tag = info[tag]->d_tag; \ + temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \ + info[tag] = temp + cnt++; \ + } \ + else \ + info[tag]->d_un.d_ptr += l_addr; \ + } \ + while (0) + + ADJUST_DYN_INFO (DT_HASH); + ADJUST_DYN_INFO (DT_PLTGOT); + ADJUST_DYN_INFO (DT_STRTAB); + ADJUST_DYN_INFO (DT_SYMTAB); +# if ! ELF_MACHINE_NO_RELA + ADJUST_DYN_INFO (DT_RELA); +# endif +# if ! ELF_MACHINE_NO_REL + ADJUST_DYN_INFO (DT_REL); +# endif + ADJUST_DYN_INFO (DT_JMPREL); + ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); + ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM + + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM); +# undef ADJUST_DYN_INFO + assert (cnt <= DL_RO_DYN_TEMP_CNT); + } +#endif + if (info[DT_PLTREL] != NULL) + { +#if ELF_MACHINE_NO_RELA + assert (info[DT_PLTREL]->d_un.d_val == DT_REL); +#elif ELF_MACHINE_NO_REL + assert (info[DT_PLTREL]->d_un.d_val == DT_RELA); +#else + assert (info[DT_PLTREL]->d_un.d_val == DT_REL + || info[DT_PLTREL]->d_un.d_val == DT_RELA); +#endif + } +#if ! ELF_MACHINE_NO_RELA + if (info[DT_RELA] != NULL) + assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela))); +# endif +# if ! ELF_MACHINE_NO_REL + if (info[DT_REL] != NULL) + assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); +#endif +#ifdef RTLD_BOOTSTRAP + /* Only the bind now flags are allowed. */ + assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL + || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0); + assert (info[DT_FLAGS] == NULL + || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0); + /* Flags must not be set for ld.so. */ + assert (info[DT_RUNPATH] == NULL); + assert (info[DT_RPATH] == NULL); +#else + if (info[DT_FLAGS] != NULL) + { + /* Flags are used. Translate to the old form where available. + Since these l_info entries are only tested for NULL pointers it + is ok if they point to the DT_FLAGS entry. */ + l->l_flags = info[DT_FLAGS]->d_un.d_val; + + if (l->l_flags & DF_SYMBOLIC) + info[DT_SYMBOLIC] = info[DT_FLAGS]; + if (l->l_flags & DF_TEXTREL) + info[DT_TEXTREL] = info[DT_FLAGS]; + if (l->l_flags & DF_BIND_NOW) + info[DT_BIND_NOW] = info[DT_FLAGS]; + } + if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) + { + l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; + + if (l->l_flags_1 & DF_1_NOW) + info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)]; + } + if (info[DT_RUNPATH] != NULL) + /* If both RUNPATH and RPATH are given, the latter is ignored. */ + info[DT_RPATH] = NULL; +#endif +} diff --git a/libc/elf/rtld.c b/libc/elf/rtld.c index 1ba35321b..0c5aebefa 100644 --- a/libc/elf/rtld.c +++ b/libc/elf/rtld.c @@ -255,15 +255,6 @@ RTLD_START # error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START" #endif -#ifndef VALIDX -# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALTAGIDX (tag)) -#endif -#ifndef ADDRIDX -# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag)) -#endif - /* This is the second half of _dl_start (below). It can be inlined safely under DONT_USE_BOOTSTRAP_MAP, where it is careful not to make any GOT references. When the tools don't permit us to avoid using a GOT entry @@ -883,6 +874,7 @@ security_init (void) _dl_random = NULL; } +#include "setup-vdso.h" /* The library search path. */ static const char *library_path attribute_relro; @@ -1339,102 +1331,9 @@ of this helper program; chances are you did not intend to run this program.\n\ } struct link_map **first_preload = &GL(dl_rtld_map).l_next; -#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO /* Set up the data structures for the system-supplied DSO early, so they can influence _dl_init_paths. */ - if (GLRO(dl_sysinfo_dso) != NULL) - { - /* Do an abridged version of the work _dl_map_object_from_fd would do - to map in the object. It's already mapped and prelinked (and - better be, since it's read-only and so we couldn't relocate it). - We just want our data structures to describe it as if we had just - mapped and relocated it normally. */ - struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, - 0, LM_ID_BASE); - if (__builtin_expect (l != NULL, 1)) - { - static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; - - l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso) - + GLRO(dl_sysinfo_dso)->e_phoff); - l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum; - for (uint_fast16_t i = 0; i < l->l_phnum; ++i) - { - const ElfW(Phdr) *const ph = &l->l_phdr[i]; - if (ph->p_type == PT_DYNAMIC) - { - l->l_ld = (void *) ph->p_vaddr; - l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); - } - else if (ph->p_type == PT_LOAD) - { - if (! l->l_addr) - l->l_addr = ph->p_vaddr; - if (ph->p_vaddr + ph->p_memsz >= l->l_map_end) - l->l_map_end = ph->p_vaddr + ph->p_memsz; - if ((ph->p_flags & PF_X) - && ph->p_vaddr + ph->p_memsz >= l->l_text_end) - l->l_text_end = ph->p_vaddr + ph->p_memsz; - } - else - /* There must be no TLS segment. */ - assert (ph->p_type != PT_TLS); - } - l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso); - l->l_addr = l->l_map_start - l->l_addr; - l->l_map_end += l->l_addr; - l->l_text_end += l->l_addr; - l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr); - elf_get_dynamic_info (l, dyn_temp); - _dl_setup_hash (l); - l->l_relocated = 1; - - /* The vDSO is always used. */ - l->l_used = 1; - - /* Initialize l_local_scope to contain just this map. This allows - the use of dl_lookup_symbol_x to resolve symbols within the vdso. - So we create a single entry list pointing to l_real as its only - element */ - l->l_local_scope[0]->r_nlist = 1; - l->l_local_scope[0]->r_list = &l->l_real; - - /* Now that we have the info handy, use the DSO image's soname - so this object can be looked up by name. Note that we do not - set l_name here. That field gives the file name of the DSO, - and this DSO is not associated with any file. */ - if (l->l_info[DT_SONAME] != NULL) - { - /* Work around a kernel problem. The kernel cannot handle - addresses in the vsyscall DSO pages in writev() calls. */ - const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_SONAME]->d_un.d_val); - size_t len = strlen (dsoname); - char *copy = malloc (len); - if (copy == NULL) - _dl_fatal_printf ("out of memory\n"); - l->l_libname->name = l->l_name = memcpy (copy, dsoname, len); - } - - /* Add the vDSO to the object list. */ - _dl_add_to_namespace_list (l, LM_ID_BASE); - - /* Rearrange the list so this DSO appears after rtld_map. */ - assert (l->l_next == NULL); - assert (l->l_prev == main_map); - GL(dl_rtld_map).l_next = l; - l->l_prev = &GL(dl_rtld_map); - first_preload = &l->l_next; - - /* We have a prelinked DSO preloaded by the system. */ - GLRO(dl_sysinfo_map) = l; -# ifdef NEED_DL_SYSINFO - if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT) - GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr; -# endif - } - } -#endif + setup_vdso (main_map, &first_preload); #ifdef DL_SYSDEP_OSCHECK DL_SYSDEP_OSCHECK (_dl_fatal_printf); @@ -2410,7 +2309,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", _dl_debug_state (); LIBC_PROBE (init_complete, 2, LM_ID_BASE, r); -#ifndef MAP_COPY +#if defined USE_LDCONFIG && !defined MAP_COPY /* We must munmap() the cache file. */ _dl_unload_cache (); #endif diff --git a/libc/elf/setup-vdso.h b/libc/elf/setup-vdso.h new file mode 100644 index 000000000..f8f348a5f --- /dev/null +++ b/libc/elf/setup-vdso.h @@ -0,0 +1,121 @@ +/* Set up the data structures for the system-supplied DSO. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +static inline void __attribute__ ((always_inline)) +setup_vdso (struct link_map *main_map __attribute__ ((unused)), + struct link_map ***first_preload __attribute__ ((unused))) +{ +#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO + if (GLRO(dl_sysinfo_dso) == NULL) + return; + + /* Do an abridged version of the work _dl_map_object_from_fd would do + to map in the object. It's already mapped and prelinked (and + better be, since it's read-only and so we couldn't relocate it). + We just want our data structures to describe it as if we had just + mapped and relocated it normally. */ + struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, + 0, LM_ID_BASE); + if (__builtin_expect (l != NULL, 1)) + { + static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; + + l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso) + + GLRO(dl_sysinfo_dso)->e_phoff); + l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum; + for (uint_fast16_t i = 0; i < l->l_phnum; ++i) + { + const ElfW(Phdr) *const ph = &l->l_phdr[i]; + if (ph->p_type == PT_DYNAMIC) + { + l->l_ld = (void *) ph->p_vaddr; + l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); + } + else if (ph->p_type == PT_LOAD) + { + if (! l->l_addr) + l->l_addr = ph->p_vaddr; + if (ph->p_vaddr + ph->p_memsz >= l->l_map_end) + l->l_map_end = ph->p_vaddr + ph->p_memsz; + if ((ph->p_flags & PF_X) + && ph->p_vaddr + ph->p_memsz >= l->l_text_end) + l->l_text_end = ph->p_vaddr + ph->p_memsz; + } + else + /* There must be no TLS segment. */ + assert (ph->p_type != PT_TLS); + } + l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso); + l->l_addr = l->l_map_start - l->l_addr; + l->l_map_end += l->l_addr; + l->l_text_end += l->l_addr; + l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr); + elf_get_dynamic_info (l, dyn_temp); + _dl_setup_hash (l); + l->l_relocated = 1; + + /* The vDSO is always used. */ + l->l_used = 1; + + /* Initialize l_local_scope to contain just this map. This allows + the use of dl_lookup_symbol_x to resolve symbols within the vdso. + So we create a single entry list pointing to l_real as its only + element */ + l->l_local_scope[0]->r_nlist = 1; + l->l_local_scope[0]->r_list = &l->l_real; + + /* Now that we have the info handy, use the DSO image's soname + so this object can be looked up by name. Note that we do not + set l_name here. That field gives the file name of the DSO, + and this DSO is not associated with any file. */ + if (l->l_info[DT_SONAME] != NULL) + { + /* Work around a kernel problem. The kernel cannot handle + addresses in the vsyscall DSO pages in writev() calls. */ + const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB]) + + l->l_info[DT_SONAME]->d_un.d_val); + size_t len = strlen (dsoname); + char *copy = malloc (len); + if (copy == NULL) + _dl_fatal_printf ("out of memory\n"); + l->l_libname->name = l->l_name = memcpy (copy, dsoname, len); + } + + /* Add the vDSO to the object list. */ + _dl_add_to_namespace_list (l, LM_ID_BASE); + +# ifdef IS_IN_rtld + /* Rearrange the list so this DSO appears after rtld_map. */ + assert (l->l_next == NULL); + assert (l->l_prev == main_map); + GL(dl_rtld_map).l_next = l; + l->l_prev = &GL(dl_rtld_map); + *first_preload = &l->l_next; +# else + GL(dl_nns) = 1; +# endif + + /* We have a prelinked DSO preloaded by the system. */ + GLRO(dl_sysinfo_map) = l; +# ifdef NEED_DL_SYSINFO + if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT) + GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr; +# endif + } +#endif +} diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h index 0a0e4a653..fd125ecb9 100644 --- a/libc/include/sys/mman.h +++ b/libc/include/sys/mman.h @@ -10,11 +10,12 @@ extern void *__mmap64 (void *__addr, size_t __len, int __prot, extern int __munmap (void *__addr, size_t __len); extern int __mprotect (void *__addr, size_t __len, int __prot); +extern int __madvise (void *__addr, size_t __len, int __advice); +libc_hidden_proto (__madvise) + /* This one is Linux specific. */ extern void *__mremap (void *__addr, size_t __old_len, size_t __new_len, int __flags, ...); - -libc_hidden_proto (madvise); #endif #endif diff --git a/libc/io/open.c b/libc/io/open.c index 0916b1e01..b6911206a 100644 --- a/libc/io/open.c +++ b/libc/io/open.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991,1995,1996,1997,2002,2007 Free Software Foundation, Inc. +/* Open a file by name. Stub version. + Copyright (C) 1991-2012 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 @@ -26,7 +27,7 @@ extern char **__libc_argv attribute_hidden; /* Open FILE with access OFLAG. If OFLAG includes O_CREAT, a third argument is the file protection. */ int -__open (file, oflag) +__libc_open (file, oflag) const char *file; int oflag; { @@ -49,10 +50,12 @@ __open (file, oflag) __set_errno (ENOSYS); return -1; } -libc_hidden_def (__open) -stub_warning (open) +libc_hidden_def (__libc_open) +weak_alias (__libc_open, __open) +libc_hidden_weak (__open) +weak_alias (__libc_open, open) -weak_alias (__open, open) +stub_warning (open) int diff --git a/libc/io/openat.c b/libc/io/openat.c index 92a5769e9..b49653936 100644 --- a/libc/io/openat.c +++ b/libc/io/openat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2005-2012 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 @@ -21,6 +21,13 @@ #include <stddef.h> #include <stdio.h> #include <sys/stat.h> +#include <kernel-features.h> + +/* Some mostly-generic code (e.g. sysdeps/posix/getcwd.c) uses this variable + if __ASSUME_ATFCTS is not defined. */ +#ifndef __ASSUME_ATFCTS +int __have_atfcts; +#endif /* Open FILE with access OFLAG. Interpret relative paths relative to the directory associated with FD. If OFLAG includes O_CREAT, a diff --git a/libc/io/tst-mknodat.c b/libc/io/tst-mknodat.c index 9158c0dfd..cba4dffad 100644 --- a/libc/io/tst-mknodat.c +++ b/libc/io/tst-mknodat.c @@ -80,8 +80,8 @@ do_test (void) } closedir (dir); - /* Create a new directory. */ - int e = mknodat (dir_fd, "some-sock", 0777 | S_IFSOCK, 0); + /* Create a new fifo. */ + int e = mknodat (dir_fd, "some-fifo", 0777 | S_IFIFO, 0); if (e == -1) { if (errno == ENOSYS) @@ -90,19 +90,19 @@ do_test (void) return 0; } - puts ("socket creation failed"); + puts ("fifo creation failed"); return 1; } struct stat64 st1; - if (fstatat64 (dir_fd, "some-sock", &st1, 0) != 0) + if (fstatat64 (dir_fd, "some-fifo", &st1, 0) != 0) { puts ("fstat64 failed"); return 1; } - if (!S_ISSOCK (st1.st_mode)) + if (!S_ISFIFO (st1.st_mode)) { - puts ("mknodat did not create a Unix domain socket"); + puts ("mknodat did not create a fifo"); return 1; } @@ -124,15 +124,15 @@ do_test (void) puts ("2nd fdopendir failed"); return 1; } - bool has_some_sock = false; + bool has_some_fifo = false; while ((d = readdir64 (dir)) != NULL) - if (strcmp (d->d_name, "some-sock") == 0) + if (strcmp (d->d_name, "some-fifo") == 0) { - has_some_sock = true; + has_some_fifo = true; #ifdef _DIRENT_HAVE_D_TYPE - if (d->d_type != DT_UNKNOWN && d->d_type != DT_SOCK) + if (d->d_type != DT_UNKNOWN && d->d_type != DT_FIFO) { - puts ("d_type for some-sock wrong"); + puts ("d_type for some-fifo wrong"); return 1; } #endif @@ -144,13 +144,13 @@ do_test (void) } closedir (dir); - if (!has_some_sock) + if (!has_some_fifo) { - puts ("some-sock not in directory list"); + puts ("some-fifo not in directory list"); return 1; } - if (unlinkat (dir_fd, "some-sock", 0) != 0) + if (unlinkat (dir_fd, "some-fifo", 0) != 0) { puts ("unlinkat failed"); return 1; diff --git a/libc/libidn/ChangeLog b/libc/libidn/ChangeLog index 58a95b1b9..07af658b2 100644 --- a/libc/libidn/ChangeLog +++ b/libc/libidn/ChangeLog @@ -1,3 +1,9 @@ +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * configure.in: If $shared != yes, just disable the add-on entirely + and issue a warning. + * configure: Regenerated. + 2012-03-07 Ulrich Drepper <drepper@gmail.com> * Makefile (distribute): Remove variable. diff --git a/libc/libidn/configure b/libc/libidn/configure index c6ba2eebc..39ed16352 100644 --- a/libc/libidn/configure +++ b/libc/libidn/configure @@ -1,8 +1,16 @@ # This file is generated from configure.in by Autoconf. DO NOT EDIT! libc_add_on_canonical= -libc_add_on_subdirs=. -# Get this defined in config.h for main source code to test. -$as_echo "#define HAVE_LIBIDN 1" >>confdefs.h +if test "$shared" = yes; then : + libc_add_on_subdirs=. + + # Get this defined in config.h for main source code to test. + $as_echo "#define HAVE_LIBIDN 1" >>confdefs.h + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libidn add-on ignored with --disable-shared" >&5 +$as_echo "$as_me: WARNING: libidn add-on ignored with --disable-shared" >&2;} +fi diff --git a/libc/libidn/configure.in b/libc/libidn/configure.in index 38b9ad7fa..16740ffb9 100644 --- a/libc/libidn/configure.in +++ b/libc/libidn/configure.in @@ -2,7 +2,10 @@ dnl glibc configure fragment for libidn add-on GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. libc_add_on_canonical= -libc_add_on_subdirs=. -# Get this defined in config.h for main source code to test. -AC_DEFINE([HAVE_LIBIDN]) +AS_IF([test "$shared" = yes], [ + libc_add_on_subdirs=. + + # Get this defined in config.h for main source code to test. + AC_DEFINE([HAVE_LIBIDN]) +], [AC_MSG_WARN([libidn add-on ignored with --disable-shared])]) diff --git a/libc/libio/Makefile b/libc/libio/Makefile index d66e090e6..ae1621fbd 100644 --- a/libc/libio/Makefile +++ b/libc/libio/Makefile @@ -77,7 +77,8 @@ tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \ += bug-rewind bug-rewind2 bug-ungetwc1 \ bug-wfflush bug-wmemstream1 tst-fopenloc2 \ tst_getwc \ - tst_putwc tst_wprintf tst_wprintf2 tst_wscanf tst-fgetwc bug-wsetpos + tst_putwc tst_wprintf tst_wprintf2 tst_wscanf \ + tst-fgetwc bug-wsetpos tst-fseek tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \ += tst_swprintf tst_swscanf \ tst-sscanf \ @@ -180,6 +181,7 @@ bug-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata tst-swscanf-ENV = LOCPATH=$(common-objpfx)localedata bug-ftell-ENV = LOCPATH=$(common-objpfx)localedata tst-fgetwc-ENV = LOCPATH=$(common-objpfx)localedata +tst-fseek-ENV = LOCPATH=$(common-objpfx)localedata generated = tst-fopenloc.mtrace tst-fopenloc.check diff --git a/libc/libio/filedoalloc.c b/libc/libio/filedoalloc.c index b7733c7f8..c9b0f0172 100644 --- a/libc/libio/filedoalloc.c +++ b/libc/libio/filedoalloc.c @@ -96,7 +96,7 @@ _IO_file_doallocate (fp) { _IO_size_t size; char *p; - struct _G_stat64 st; + struct stat64 st; #ifndef _LIBC /* If _IO_cleanup_registration_needed is non-zero, we should call the diff --git a/libc/libio/fileops.c b/libc/libio/fileops.c index a65f0afbc..7033dd165 100644 --- a/libc/libio/fileops.c +++ b/libc/libio/fileops.c @@ -643,7 +643,7 @@ libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow) static int mmap_remap_check (_IO_FILE *fp) { - struct _G_stat64 st; + struct stat64 st; if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode) && st.st_size != 0 @@ -771,7 +771,7 @@ decide_maybe_mmap (_IO_FILE *fp) file descriptors are for mmap-able objects and on 32-bit machines we don't want to map files which are too large since this would require too much virtual memory. */ - struct _G_stat64 st; + struct stat64 st; if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode) && st.st_size != 0 @@ -986,6 +986,9 @@ _IO_new_file_seekoff (fp, offset, dir, mode) int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end && fp->_IO_write_base == fp->_IO_write_ptr); + bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base + || _IO_in_put_mode (fp)); + if (mode == 0) dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ @@ -996,10 +999,8 @@ _IO_new_file_seekoff (fp, offset, dir, mode) which assumes file_ptr() is eGptr. Anyway, since we probably end up flushing when we close(), it doesn't make much difference.) FIXME: simulate mem-mapped files. */ - - if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp)) - if (_IO_switch_to_get_mode (fp)) - return EOF; + else if (was_writing && _IO_switch_to_get_mode (fp)) + return EOF; if (fp->_IO_buf_base == NULL) { @@ -1018,7 +1019,17 @@ _IO_new_file_seekoff (fp, offset, dir, mode) { case _IO_seek_cur: /* Adjust for read-ahead (bytes is buffer). */ - offset -= fp->_IO_read_end - fp->_IO_read_ptr; + if (mode != 0 || !was_writing) + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + else + { + /* _IO_read_end coincides with fp._offset, so the actual file position + is fp._offset - (_IO_read_end - new_write_ptr). This is fine + even if fp._offset is not set, since fp->_IO_read_end is then at + _IO_buf_base and this adjustment is for unbuffered output. */ + offset -= fp->_IO_read_end - fp->_IO_write_ptr; + } + if (fp->_offset == _IO_pos_BAD) { if (mode != 0) @@ -1046,7 +1057,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode) break; case _IO_seek_end: { - struct _G_stat64 st; + struct stat64 st; if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) { offset += st.st_size; @@ -1247,7 +1258,7 @@ _IO_file_stat (fp, st) void *st; { #ifdef _G_FSTAT64 - return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st); + return _G_FSTAT64 (fp->_fileno, (struct stat64 *) st); #else return fstat (fp->_fileno, (struct stat *) st); #endif diff --git a/libc/libio/libio.h b/libc/libio/libio.h index f093a93e9..45f4707e6 100644 --- a/libc/libio/libio.h +++ b/libc/libio/libio.h @@ -37,7 +37,7 @@ #define _IO_size_t size_t #define _IO_ssize_t __ssize_t #define _IO_off_t __off_t -#define _IO_off64_t _G_off64_t +#define _IO_off64_t __off64_t #define _IO_pid_t __pid_t #define _IO_uid_t __uid_t #define _IO_iconv_t _G_iconv_t diff --git a/libc/libio/oldfileops.c b/libc/libio/oldfileops.c index 8fda0484a..aa4e3f5f9 100644 --- a/libc/libio/oldfileops.c +++ b/libc/libio/oldfileops.c @@ -530,7 +530,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode) break; case _IO_seek_end: { - struct _G_stat64 st; + struct stat64 st; if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) { offset += st.st_size; diff --git a/libc/libio/tst-fseek.c b/libc/libio/tst-fseek.c new file mode 100644 index 000000000..457a08778 --- /dev/null +++ b/libc/libio/tst-fseek.c @@ -0,0 +1,173 @@ +/* Verify that fseek/ftell combination works for wide chars. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <errno.h> +#include <wchar.h> +#include <unistd.h> +#include <string.h> + +/* Defined in test-skeleton.c. */ +static int create_temp_file (const char *base, char **filename); + + +static int +do_seek_end (FILE *fp) +{ + long save; + + if (fputws (L"abc\n", fp) == -1) + { + printf ("do_seek_end: fputws: %s\n", strerror (errno)); + return 1; + } + + save = ftell (fp); + rewind (fp); + + if (fseek (fp, 0, SEEK_END) == -1) + { + printf ("do_seek_end: fseek: %s\n", strerror (errno)); + return 1; + } + + if (save != ftell (fp)) + { + printf ("save = %ld, ftell = %ld\n", save, ftell (fp)); + return 1; + } + + return 0; +} + +int +do_seek_set (FILE *fp) +{ + long save1, save2; + + if (fputws (L"ゅう\n", fp) == -1) + { + printf ("seek_set: fputws(1): %s\n", strerror (errno)); + return 1; + } + + save1 = ftell (fp); + + if (fputws (L"ゅう\n", fp) == -1) + { + printf ("seek_set: fputws(2): %s\n", strerror (errno)); + return 1; + } + + save2 = ftell (fp); + + if (fputws (L"ゅう\n", fp) == -1) + { + printf ("seek_set: fputws(3): %s\n", strerror (errno)); + return 1; + } + + if (fseek (fp, save1, SEEK_SET) == -1) + { + printf ("seek_set: fseek(1): %s\n", strerror (errno)); + return 1; + } + + if (save1 != ftell (fp)) + { + printf ("save1 = %ld, ftell = %ld\n", save1, ftell (fp)); + return 1; + } + + if (fseek (fp, save2, SEEK_SET) == -1) + { + printf ("seek_set: fseek(2): %s\n", strerror (errno)); + return 1; + } + + if (save2 != ftell (fp)) + { + printf ("save2 = %ld, ftell = %ld\n", save2, ftell (fp)); + return 1; + } + + return 0; +} + +static int +do_test (void) +{ + if (setlocale (LC_ALL, "ja_JP.UTF-8") == NULL) + { + printf ("Cannot set ja_JP.UTF-8 locale.\n"); + exit (1); + } + + /* Retain messages in English. */ + if (setlocale (LC_MESSAGES, "en_US.ISO-8859-1") == NULL) + { + printf ("Cannot set LC_MESSAGES to en_US.ISO-8859-1 locale.\n"); + exit (1); + } + + int ret = 0; + char *filename; + int fd = create_temp_file ("tst-fseek.out", &filename); + + if (fd == -1) + return 1; + + FILE *fp = fdopen (fd, "w+"); + if (fp == NULL) + { + printf ("seek_set: fopen: %s\n", strerror (errno)); + close (fd); + return 1; + } + + if (do_seek_set (fp)) + { + printf ("SEEK_SET test failed\n"); + ret = 1; + } + + /* Reopen the file. */ + fclose (fp); + fp = fopen (filename, "w+"); + if (fp == NULL) + { + printf ("seek_end: fopen: %s\n", strerror (errno)); + return 1; + } + + if (do_seek_end (fp)) + { + printf ("SEEK_END test failed\n"); + ret = 1; + } + + fclose (fp); + + return ret; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/libc/libio/wfileops.c b/libc/libio/wfileops.c index b790029ff..44b1236c0 100644 --- a/libc/libio/wfileops.c +++ b/libc/libio/wfileops.c @@ -545,6 +545,57 @@ _IO_wfile_sync (fp) } libc_hidden_def (_IO_wfile_sync) +/* Adjust the internal buffer pointers to reflect the state in the external + buffer. The content between fp->_IO_read_base and fp->_IO_read_ptr is + assumed to be converted and available in the range + fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end. + + Returns 0 on success and -1 on error with the _IO_ERR_SEEN flag set. */ +static inline int +adjust_wide_data (_IO_FILE *fp, bool do_convert) +{ + struct _IO_codecvt *cv = fp->_codecvt; + + int clen = (*cv->__codecvt_do_encoding) (cv); + + /* Take the easy way out for constant length encodings if we don't need to + convert. */ + if (!do_convert && clen > 0) + { + fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base) + / clen); + goto done; + } + + enum __codecvt_result status; + const char *read_stop = (const char *) fp->_IO_read_base; + do + { + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, fp->_IO_read_ptr, + &read_stop, + fp->_wide_data->_IO_read_base, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + /* Should we return EILSEQ? */ + if (__builtin_expect (status == __codecvt_error, 0)) + { + fp->_flags |= _IO_ERR_SEEN; + return -1; + } + } + while (__builtin_expect (status == __codecvt_partial, 0)); + +done: + /* Now seek to _IO_read_end to behave as if we have read it all in. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + + return 0; +} + _IO_off64_t _IO_wfile_seekoff (fp, offset, dir, mode) _IO_FILE *fp; @@ -562,6 +613,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode) && (fp->_wide_data->_IO_write_base == fp->_wide_data->_IO_write_ptr)); + bool was_writing = ((fp->_wide_data->_IO_write_ptr + > fp->_wide_data->_IO_write_base) + || _IO_in_put_mode (fp)); + if (mode == 0) { /* XXX For wide stream with backup store it is not very @@ -593,11 +648,8 @@ _IO_wfile_seekoff (fp, offset, dir, mode) which assumes file_ptr() is eGptr. Anyway, since we probably end up flushing when we close(), it doesn't make much difference.) FIXME: simulate mem-mapped files. */ - - if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base - || _IO_in_put_mode (fp)) - if (_IO_switch_to_wget_mode (fp)) - return WEOF; + else if (was_writing && _IO_switch_to_wget_mode (fp)) + return WEOF; if (fp->_wide_data->_IO_buf_base == NULL) { @@ -628,29 +680,104 @@ _IO_wfile_seekoff (fp, offset, dir, mode) cv = fp->_codecvt; clen = (*cv->__codecvt_do_encoding) (cv); - if (clen > 0) + if (mode != 0 || !was_writing) { - offset -= (fp->_wide_data->_IO_read_end - - fp->_wide_data->_IO_read_ptr) * clen; - /* Adjust by readahead in external buffer. */ - offset -= fp->_IO_read_end - fp->_IO_read_ptr; + if (clen > 0) + { + offset -= (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr) * clen; + /* Adjust by readahead in external buffer. */ + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + } + else + { + int nread; + + flushed: + delta = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, + &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } } else { - int nread; + char *new_write_ptr = fp->_IO_write_ptr; - delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base; - fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; - nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, - fp->_IO_read_base, - fp->_IO_read_end, delta); - fp->_IO_read_ptr = fp->_IO_read_base + nread; - fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; - offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + if (clen > 0) + offset += (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base) / clen; + else + { + enum __codecvt_result status; + delta = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + const wchar_t *write_base = fp->_wide_data->_IO_write_base; + + /* FIXME: This actually ends up in two iterations of conversion, + one here and the next when the buffer actually gets flushed. + It may be possible to optimize this in future so that + wdo_write identifies already converted content and does not + redo it. In any case, this is much better than having to + flush buffers for every ftell. */ + do + { + /* Ugh, no point trying to avoid the flush. Just do it + and go back to how it was with the read mode. */ + if (delta > 0 && new_write_ptr == fp->_IO_buf_end) + { + if (_IO_switch_to_wget_mode (fp)) + return WEOF; + goto flushed; + } + + const wchar_t *new_wbase = fp->_wide_data->_IO_write_base; + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + status = (*cv->__codecvt_do_out) (cv, + &fp->_wide_data->_IO_state, + write_base, + write_base + delta, + &new_wbase, + new_write_ptr, + fp->_IO_buf_end, + &new_write_ptr); + + delta -= new_wbase - write_base; + + /* If there was an error, then return WEOF. + TODO: set buffer state. */ + if (__builtin_expect (status == __codecvt_error, 0)) + return WEOF; + } + while (delta > 0); + } + + /* _IO_read_end coincides with fp._offset, so the actual file position + is fp._offset - (_IO_read_end - new_write_ptr). This is fine + even if fp._offset is not set, since fp->_IO_read_end is then at + _IO_buf_base and this adjustment is for unbuffered output. */ + offset -= fp->_IO_read_end - new_write_ptr; } if (fp->_offset == _IO_pos_BAD) - goto dumb; + { + if (mode != 0) + goto dumb; + else + { + result = _IO_SYSSEEK (fp, 0, dir); + if (result == EOF) + return result; + fp->_offset = result; + } + } + /* Make offset absolute, assuming current pointer is file_ptr(). */ offset += fp->_offset; @@ -660,7 +787,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode) break; case _IO_seek_end: { - struct _G_stat64 st; + struct stat64 st; if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) { offset += st.st_size; @@ -693,6 +820,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode) fp->_wide_data->_IO_buf_base); _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + + if (adjust_wide_data (fp, false)) + goto dumb; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); goto resync; } @@ -733,6 +864,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode) _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + + if (adjust_wide_data (fp, true)) + goto dumb; + fp->_offset = result + count; _IO_mask_flags (fp, 0, _IO_EOF_SEEN); return offset; diff --git a/libc/malloc/arena.c b/libc/malloc/arena.c index b209e3b7c..eb9180eb9 100644 --- a/libc/malloc/arena.c +++ b/libc/malloc/arena.c @@ -634,7 +634,7 @@ shrink_heap(heap_info *h, long diff) h->mprotect_size = new_size; } else - madvise ((char *)h + new_size, diff, MADV_DONTNEED); + __madvise ((char *)h + new_size, diff, MADV_DONTNEED); /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/ h->size = new_size; diff --git a/libc/malloc/malloc.c b/libc/malloc/malloc.c index ca1d73f87..3f0b6b1cd 100644 --- a/libc/malloc/malloc.c +++ b/libc/malloc/malloc.c @@ -4450,7 +4450,7 @@ static int mtrim(mstate av, size_t pad) content. */ memset (paligned_mem, 0x89, size & ~psm1); #endif - madvise (paligned_mem, size & ~psm1, MADV_DONTNEED); + __madvise (paligned_mem, size & ~psm1, MADV_DONTNEED); result = 1; } @@ -4899,8 +4899,7 @@ malloc_printerr(int action, const char *str, void *ptr) while (cp > buf) *--cp = '0'; - __libc_message (action & 2, - "*** glibc detected *** %s: %s: 0x%s ***\n", + __libc_message (action & 2, "*** Error in `%s': %s: 0x%s ***\n", __libc_argv[0] ?: "<unknown>", str, cp); } else if (action & 2) diff --git a/libc/manual/platform.texi b/libc/manual/platform.texi index 02b5c554a..e387ff4cc 100644 --- a/libc/manual/platform.texi +++ b/libc/manual/platform.texi @@ -26,3 +26,11 @@ different from the processor frequency. More information is available in without requiring assistance from the operating system, so it is very efficient. @end deftypefun + +@deftypefun {uint64_t} __ppc_get_timebase_freq (void) +Read the current frequency at which the Time Base Register is updated. + +This frequency is not related to the processor clock or the bus clock. +It is also possible that this frequency is not constant. More information is +available in @cite{Power ISA 2.06b - Book II - Section 5.2}. +@end deftypefun diff --git a/libc/math/Makefile b/libc/math/Makefile index c390d5511..5491c5b83 100644 --- a/libc/math/Makefile +++ b/libc/math/Makefile @@ -60,7 +60,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod \ s_catan s_casin s_ccos s_csin s_ctan s_ctanh s_cacos \ s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj s_clog10 \ s_fma s_lrint s_llrint s_lround s_llround e_exp10 w_log2 \ - s_isinf_ns $(calls:s_%=m_%) + s_isinf_ns $(calls:s_%=m_%) x2y2m1 include ../Makeconfig diff --git a/libc/math/gen-libm-test.pl b/libc/math/gen-libm-test.pl index c2c22a5b1..5d9b2ea4b 100755 --- a/libc/math/gen-libm-test.pl +++ b/libc/math/gen-libm-test.pl @@ -323,7 +323,9 @@ sub parse_args { } # Special handling for some macros: $cline .= " (\"$str\", "; - if ($args[0] =~ /fpclassify|isnormal|isfinite|signbit/) { + if ($args[0] =~ /fpclassify|isnormal|isfinite|isinf|isnan|signbit + |isgreater|isgreaterequal|isless|islessequal + |islessgreater|isunordered/x) { $c_call = "$args[0] ("; } else { $c_call = " FUNC($args[0]) ("; diff --git a/libc/math/libm-test.inc b/libc/math/libm-test.inc index 83d58998f..df860ebe2 100644 --- a/libc/math/libm-test.inc +++ b/libc/math/libm-test.inc @@ -40,13 +40,13 @@ /* This testsuite has currently tests for: acos, acosh, asin, asinh, atan, atan2, atanh, cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1, - fabs, fdim, floor, fma, fmax, fmin, fmod, fpclassify, + fabs, fdim, finite, floor, fma, fmax, fmin, fmod, fpclassify, frexp, gamma, hypot, ilogb, isfinite, isinf, isnan, isnormal, isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered, j0, j1, jn, ldexp, lgamma, log, log10, log1p, log2, logb, - modf, nearbyint, nextafter, + modf, nearbyint, nextafter, nexttoward, pow, remainder, remquo, rint, lrint, llrint, round, lround, llround, scalb, scalbn, scalbln, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc, @@ -54,10 +54,14 @@ and for the following complex math functions: cabs, cacos, cacosh, carg, casin, casinh, catan, catanh, - ccos, ccosh, cexp, clog, cpow, cproj, csin, csinh, csqrt, ctan, ctanh. + ccos, ccosh, cexp, cimag, clog, clog10, conj, cpow, cproj, creal, + csin, csinh, csqrt, ctan, ctanh. - At the moment the following functions aren't tested: - drem, nan + At the moment the following functions and macros aren't tested: + drem (alias for remainder), + lgamma_r, + nan, + pow10 (alias for exp10). Parameter handling is primitive in the moment: --verbose=[0..3] for different levels of output: @@ -83,8 +87,9 @@ aren't checked at the moment. NaN values: There exist signalling and quiet NaNs. This implementation - only uses quiet NaN as parameter but does not differenciate - between the two kinds of NaNs as result. + only uses quiet NaN as parameter but does not differentiate + between the two kinds of NaNs as result. Where the sign of a NaN is + significant, this is not tested. Inline functions: Inlining functions should give an improvement in speed - but not in precission. The inlined functions return @@ -215,6 +220,7 @@ static int ignore_max_ulp; /* Should we ignore max_ulp? */ static FLOAT minus_zero, plus_zero; static FLOAT plus_infty, minus_infty, nan_value, max_value, min_value; +static FLOAT min_subnorm_value; static FLOAT max_error, real_max_error, imag_max_error; @@ -2503,6 +2509,66 @@ clog_test (void) TEST_c_c (clog, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 9.868649107778739752403260515979017248596e-19L, 1.061846605795612822522063052130030717368e-301L); #endif + TEST_c_c (clog, 0x0.ffffffp0L, 0x0.ffffffp-100L, -5.960464655174753498633255797994360530379e-8L, 7.888609052210118054117285652827862296732e-31L); +#ifndef TEST_FLOAT + TEST_c_c (clog, 0x0.fffffffffffff8p0L, 0x0.fffffffffffff8p-1000L, -1.110223024625156602053389888482372171810e-16L, 9.332636185032188789900895447238171696171e-302L); +#endif +#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381 + TEST_c_c (clog, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp-15000L, -5.421010862427522170184200798202494495630e-20L, 3.548665303440282824232502561095699343814e-4516L); +#endif + + TEST_c_c (clog, 0x1a6p-10L, 0x3a5p-10L, -1.4305135209763571252847059962654228661815e-06L, 1.1460277178115757370775644871674016684074L); + TEST_c_c (clog, 0xf2p-10L, 0x3e3p-10L, 6.1988446308070710970664736815277450078106e-06L, 1.3322126499153926210226335249558203898460L); + TEST_c_c (clog, 0x4d4ep-15L, 0x6605p-15L, -1.6298145321400412054744424587143483169412e-08L, 0.9223574537155056772124552172295398141249L); + TEST_c_c (clog, 0x2818p-15L, 0x798fp-15L, 1.5366822245016167178749091974664853785194e-08L, 1.2522014929038946066987318471922169174157L); + TEST_c_c (clog, 0x9b57bp-20L, 0xcb7b4p-20L, -3.9563019528687610863490232935890272740908e-11L, 0.9187593477446338910857133065497364950682L); + TEST_c_c (clog, 0x2731p-20L, 0xfffd0p-20L, 4.4110493034041283943115971658295280288115e-11L, 1.5612279663766352262688735061954290528838L); + TEST_c_c (clog, 0x2ede88p-23L, 0x771c3fp-23L, -4.4764192352906350039050902870893173560494e-13L, 1.1959106857549200806818600493552847793381L); + TEST_c_c (clog, 0x11682p-23L, 0x7ffed1p-23L, 1.1723955140027907954461000991619077811832e-12L, 1.5622968405332756349813737986164832897108L); + TEST_c_c (clog, 0xa1f2c1p-24L, 0xc643aep-24L, -1.0480505352462576151523512837107080269981e-13L, 0.8858771987699967480545613322309315260313L); + TEST_c_c (clog, 0x659feap-24L, 0xeaf6f9p-24L, 3.7303493627403868207597214252239749960738e-14L, 1.1625816408046866464773042283673653469061L); +#ifndef TEST_FLOAT + TEST_c_c (clog, 0x4447d7175p-35L, 0x6c445e00ap-35L, -1.4823076576950255933915367361099865652625e-20L, 1.0081311552703893116404606212158840190615L); + TEST_c_c (clog, 0x2dd46725bp-35L, 0x7783a1284p-35L, 4.4469229730850767799109418892826021157328e-20L, 1.2046235979300843056806465045930070146351L); + TEST_c_c (clog, 0x164c74eea876p-45L, 0x16f393482f77p-45L, -3.0292258760486853327810377824479932031744e-26L, 0.7998237934177411746093524982030330293980L); + TEST_c_c (clog, 0xfe961079616p-45L, 0x1bc37e09e6d1p-45L, 5.3718272201930019901317065495843842735179e-26L, 1.0503831592447830576186444373011142397404L); + TEST_c_c (clog, 0xa4722f19346cp-51L, 0x7f9631c5e7f07p-51L, -6.2122796286154679676173624516405339768606e-30L, 1.4904138780720095276446375492434049214172L); + TEST_c_c (clog, 0x10673dd0f2481p-51L, 0x7ef1d17cefbd2p-51L, 3.2047474274603604594851472963586149973093e-29L, 1.4422922682185099608731642353544207976604L); + TEST_c_c (clog, 0x8ecbf810c4ae6p-52L, 0xd479468b09a37p-52L, -9.7375017988218644730510244778042114638107e-30L, 0.9790637929494922564724108399524154766631L); + TEST_c_c (clog, 0x5b06b680ea2ccp-52L, 0xef452b965da9fp-52L, 8.3076914081087805757422664530653247447136e-30L, 1.2072712126771536614482822173033535043206L); + TEST_c_c (clog, 0x659b70ab7971bp-53L, 0x1f5d111e08abecp-53L, -2.5083311595699359750201056724289010648701e-30L, 1.3710185432462268491534742969536240564640L); + TEST_c_c (clog, 0x15cfbd1990d1ffp-53L, 0x176a3973e09a9ap-53L, 1.0168910106364605304135563536838075568606e-30L, 0.8208373755522359859870890246475340086663L); + TEST_c_c (clog, 0x1367a310575591p-54L, 0x3cfcc0a0541f60p-54L, 5.0844550531823026520677817684239496041087e-32L, 1.2627468605458094918919206628466016525397L); + TEST_c_c (clog, 0x55cb6d0c83af5p-55L, 0x7fe33c0c7c4e90p-55L, -5.2000108498455368032511404449795741611813e-32L, 1.5288921536982513453421343495466824420259L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_c_c (clog, 0x298c62cb546588a7p-63L, 0x7911b1dfcc4ecdaep-63L, -1.1931267660846218205882675852805793644095e-36L, 1.2402109774337032400594953899784058127412L); + TEST_c_c (clog, 0x4d9c37e2b5cb4533p-63L, 0x65c98be2385a042ep-63L, 6.4064442119814669184296141278612389400075e-37L, 0.9193591364645830864185131402313014890145L); + TEST_c_c (clog, 0x602fd5037c4792efp-64L, 0xed3e2086dcca80b8p-64L, -2.3362950222592964220878638677292132852104e-37L, 1.1856121127236268105413184264288408265852L); + TEST_c_c (clog, 0x6b10b4f3520217b6p-64L, 0xe8893cbb449253a1p-64L, 2.4244570985709679851855191080208817099132e-37L, 1.1393074519572050614551047548718495655972L); + TEST_c_c (clog, 0x81b7efa81fc35ad1p-65L, 0x1ef4b835f1c79d812p-65L, -9.9182335850630508484862145328126979066934e-39L, 1.3146479888794807046338799047003947008804L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_c_c (clog, 0x3f96469050f650869c2p-75L, 0x6f16b2c9c8b05988335p-75L, -1.0509738482436128031927971874674370984602e-45L, 1.0509191467640012308402149909370784281448L); + TEST_c_c (clog, 0x3157fc1d73233e580c8p-75L, 0x761b52ccd435d7c7f5fp-75L, 1.3487497719126364307640897239165442763573e-43L, 1.1750493008528425228929764149024375035382L); + TEST_c_c (clog, 0x155f8afc4c48685bf63610p-85L, 0x17d0cf2652cdbeb1294e19p-85L, -4.7775669192897997174762089350332738583822e-50L, 0.8393953487996880419413728440067635213372L); + TEST_c_c (clog, 0x13836d58a13448d750b4b9p-85L, 0x195ca7bc3ab4f9161edbe6p-85L, 2.8398125044729578740243199963484494962411e-50L, 0.9149964976334130461795060758257083099706L); + TEST_c_c (clog, 0x1df515eb171a808b9e400266p-95L, 0x7c71eb0cd4688dfe98581c77p-95L, -3.5048022044913950094635368750889659723004e-57L, 1.3345633256521815205858155673950177421079L); + TEST_c_c (clog, 0xe33f66c9542ca25cc43c867p-95L, 0x7f35a68ebd3704a43c465864p-95L, 4.1101771307217268747345114262406964584250e-56L, 1.4596065864518742494094402406719567059585L); + TEST_c_c (clog, 0x6771f22c64ed551b857c128b4cp-105L, 0x1f570e7a13cc3cf2f44fd793ea1p-105L, -1.4281333889622737316199756373421183559948e-62L, 1.3673546561165378090903506783353927980633L); + TEST_c_c (clog, 0x15d8ab6ed05ca514086ac3a1e84p-105L, 0x1761e480aa094c0b10b34b09ce9p-105L, 1.0027319539522347477331743836657426754857e-62L, 0.8193464073721167323313606647411269414759L); + TEST_c_c (clog, 0x187190c1a334497bdbde5a95f48p-106L, 0x3b25f08062d0a095c4cfbbc338dp-106L, -1.7471844652198029695350765775994001163767e-63L, 1.1789110097072986038243729592318526094314L); + TEST_c_c (clog, 0x6241ef0da53f539f02fad67dabp-106L, 0x3fb46641182f7efd9caa769dac0p-106L, 4.3299788920664682288477984749202524623248e-63L, 1.4746938237585656250866370987773473745867L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_c_c (clog, 0x3e1d0a105ac4ebeacd9c6952d34cp-112L, 0xf859b3d1b06d005dcbb5516d5479p-112L, -1.1683999374665377365054966073875064467108e-66L, 1.3257197596350832748781065387304444940172L); + TEST_c_c (clog, 0x47017a2e36807acb1e5214b209dep-112L, 0xf5f4a550c9d75e3bb1839d865f0dp-112L, 1.5077923002544367932999503838191154621839e-65L, 1.2897445708311412721399861948957141824914L); + TEST_c_c (clog, 0x148f818cb7a9258fca942ade2a0cap-113L, 0x18854a34780b8333ec53310ad7001p-113L, -7.1865869169568789348552370692485515571497e-67L, 0.8730167479365994646287897223471819363668L); + TEST_c_c (clog, 0xfd95243681c055c2632286921092p-113L, 0x1bccabcd29ca2152860ec29e34ef7p-113L, 6.6255694866654064502633121109394710807528e-66L, 1.0526409614996288387567810726095850312049L); + TEST_c_c (clog, 0xdb85c467ee2aadd5f425fe0f4b8dp-114L, 0x3e83162a0f95f1dcbf97dddf410eap-114L, 4.6017338806965821566734340588575402712716e-67L, 1.3547418904611758959096647942223384691728L); + TEST_c_c (clog, 0x1415bcaf2105940d49a636e98ae59p-115L, 0x7e6a150adfcd1b0921d44b31f40f4p-115L, 2.5993421227864195179698176012564317527271e-67L, 1.4132318089683022770487383611430906982461L); +#endif + END (clog, complex); } @@ -2663,6 +2729,66 @@ clog10_test (void) TEST_c_c (clog10, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 4.285899851347756186652871946325962330640e-19L, 4.611541215247321502041995872887317363241e-302L); #endif + TEST_c_c (clog10, 0x0.ffffffp0L, 0x0.ffffffp-100L, -2.588596909321764128428416045209904492216e-8L, 3.425979381266895667295625489912064603415e-31L); +#ifndef TEST_FLOAT + TEST_c_c (clog10, 0x0.fffffffffffff8p0L, 0x0.fffffffffffff8p-1000L, -4.821637332766435821255375046554377090472e-17L, 4.053112396770095089737411317782466262176e-302L); +#endif +#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381 + TEST_c_c (clog10, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp-15000L, -2.354315103889861110220423157644627849164e-20L, 1.541165759405643564697852372112893034397e-4516L); +#endif + + TEST_c_c (clog10, 0x1a6p-10L, 0x3a5p-10L, -6.2126412844802358329771948751248003038444e-07L, 0.4977135139537443711784513409096950995985L); + TEST_c_c (clog10, 0xf2p-10L, 0x3e3p-10L, 2.6921240173351112953324592659528481616879e-06L, 0.5785726025799636431142862788413361783862L); + TEST_c_c (clog10, 0x4d4ep-15L, 0x6605p-15L, -7.0781945783414996953799915941870192015212e-09L, 0.4005747524909781155537088181659175147564L); + TEST_c_c (clog10, 0x2818p-15L, 0x798fp-15L, 6.6737261053986614395049481326819059203910e-09L, 0.5438241985991753781478398141908629586460L); + TEST_c_c (clog10, 0x9b57bp-20L, 0xcb7b4p-20L, -1.7182001068739620267773842120965071561416e-11L, 0.3990121149225253562859800593935899629087L); + TEST_c_c (clog10, 0x2731p-20L, 0xfffd0p-20L, 1.9156943718715958194239364991329064049438e-11L, 0.6780326907904082601285090019969008967595L); + TEST_c_c (clog10, 0x2ede88p-23L, 0x771c3fp-23L, -1.9440841725722970687903291200493082253766e-13L, 0.5193774116724956222518530053006822210323L); + TEST_c_c (clog10, 0x11682p-23L, 0x7ffed1p-23L, 5.0916490233953865181284669870035717560498e-13L, 0.6784968969384861816694467029319146542069L); + TEST_c_c (clog10, 0xa1f2c1p-24L, 0xc643aep-24L, -4.5516256421319921959681423447271490869664e-14L, 0.3847315790697197749315054516562206543710L); + TEST_c_c (clog10, 0x659feap-24L, 0xeaf6f9p-24L, 1.6200701438094619117335617123525612051457e-14L, 0.5049027913635038013499728086604870749732L); +#ifndef TEST_FLOAT + TEST_c_c (clog10, 0x4447d7175p-35L, 0x6c445e00ap-35L, -6.4375803621988389731799033530075237868110e-21L, 0.4378257977686804492768642780897650927167L); + TEST_c_c (clog10, 0x2dd46725bp-35L, 0x7783a1284p-35L, 1.9312741086596516918394613098872836703188e-20L, 0.5231613813514771042838490538484014771862L); + TEST_c_c (clog10, 0x164c74eea876p-45L, 0x16f393482f77p-45L, -1.3155760824064879362415202279780039150764e-26L, 0.3473590599762514228227328130640352044313L); + TEST_c_c (clog10, 0xfe961079616p-45L, 0x1bc37e09e6d1p-45L, 2.3329549194675052736016290082882121135546e-26L, 0.4561756099441139182878993697611751382976L); + TEST_c_c (clog10, 0xa4722f19346cp-51L, 0x7f9631c5e7f07p-51L, -2.6979587627476803379953050733225113494503e-30L, 0.6472785229986997177606324374555347813105L); + TEST_c_c (clog10, 0x10673dd0f2481p-51L, 0x7ef1d17cefbd2p-51L, 1.3918041236396763648388478552321724382899e-29L, 0.6263795733790237053262025311642907438291L); + TEST_c_c (clog10, 0x8ecbf810c4ae6p-52L, 0xd479468b09a37p-52L, -4.2289432987513243393180377141513840878196e-30L, 0.4252020027092323591068799049905597805296L); + TEST_c_c (clog10, 0x5b06b680ea2ccp-52L, 0xef452b965da9fp-52L, 3.6079845358966994996207055940336690133424e-30L, 0.5243112258263349992771652393178033846555L); + TEST_c_c (clog10, 0x659b70ab7971bp-53L, 0x1f5d111e08abecp-53L, -1.0893543813872082317104059174982092534059e-30L, 0.5954257879188711495921161433751775633232L); + TEST_c_c (clog10, 0x15cfbd1990d1ffp-53L, 0x176a3973e09a9ap-53L, 4.4163015461643576961232672330852798804976e-31L, 0.3564851427422832755956993418877523303529L); + TEST_c_c (clog10, 0x1367a310575591p-54L, 0x3cfcc0a0541f60p-54L, 2.2081507730821788480616336165447731164865e-32L, 0.5484039935757001196548030312819898864760L); + TEST_c_c (clog10, 0x55cb6d0c83af5p-55L, 0x7fe33c0c7c4e90p-55L, -2.2583360179249556400630343805573865814771e-32L, 0.6639894257763289307423302343317622430835L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_c_c (clog10, 0x298c62cb546588a7p-63L, 0x7911b1dfcc4ecdaep-63L, -5.1816837072162316773907242302011632570857e-37L, 0.5386167838952956925896424154370364458140L); + TEST_c_c (clog10, 0x4d9c37e2b5cb4533p-63L, 0x65c98be2385a042ep-63L, 2.7822833698845776001753149807484078521508e-37L, 0.3992725998539071066769046272515417679815L); + TEST_c_c (clog10, 0x602fd5037c4792efp-64L, 0xed3e2086dcca80b8p-64L, -1.0146400362652473358437501879334790111898e-37L, 0.5149047982335273098246594109614460842099L); + TEST_c_c (clog10, 0x6b10b4f3520217b6p-64L, 0xe8893cbb449253a1p-64L, 1.0529283395205396881397407610630442563938e-37L, 0.4947949395762683446121140513971996916447L); + TEST_c_c (clog10, 0x81b7efa81fc35ad1p-65L, 0x1ef4b835f1c79d812p-65L, -4.3074341162203896332989394770760901408798e-39L, 0.5709443672155660428417571212549720987784L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_c_c (clog10, 0x3f96469050f650869c2p-75L, 0x6f16b2c9c8b05988335p-75L, -4.5643214291682663316715446865040356750881e-46L, 0.4564083863660793840592614609053162690362L); + TEST_c_c (clog10, 0x3157fc1d73233e580c8p-75L, 0x761b52ccd435d7c7f5fp-75L, 5.8575458340992751256451490143468457830297e-44L, 0.5103174273246635294300470585396890237265L); + TEST_c_c (clog10, 0x155f8afc4c48685bf63610p-85L, 0x17d0cf2652cdbeb1294e19p-85L, -2.0748709499710785084693619097712106753591e-50L, 0.3645447681189598740620098186365764884771L); + TEST_c_c (clog10, 0x13836d58a13448d750b4b9p-85L, 0x195ca7bc3ab4f9161edbe6p-85L, 1.2333149003324592532859843519619084433953e-50L, 0.3973779298829931059309198145608711073016L); + TEST_c_c (clog10, 0x1df515eb171a808b9e400266p-95L, 0x7c71eb0cd4688dfe98581c77p-95L, -1.5221162575729652613635150540947625639689e-57L, 0.5795934880811949230121092882659698986043L); + TEST_c_c (clog10, 0xe33f66c9542ca25cc43c867p-95L, 0x7f35a68ebd3704a43c465864p-95L, 1.7850272475173865337808494725293124613817e-56L, 0.6338990862456906754888183278564382516852L); + TEST_c_c (clog10, 0x6771f22c64ed551b857c128b4cp-105L, 0x1f570e7a13cc3cf2f44fd793ea1p-105L, -6.2023045024810589256360494043570293518879e-63L, 0.5938345819561308555003145899438513900776L); + TEST_c_c (clog10, 0x15d8ab6ed05ca514086ac3a1e84p-105L, 0x1761e480aa094c0b10b34b09ce9p-105L, 4.3548095442952115860848857519953610343042e-63L, 0.3558376234889641500775150477035448866763L); + TEST_c_c (clog10, 0x187190c1a334497bdbde5a95f48p-106L, 0x3b25f08062d0a095c4cfbbc338dp-106L, -7.5879257211204444302994221436282805900756e-64L, 0.5119945461708707332160859198685423099187L); + TEST_c_c (clog10, 0x6241ef0da53f539f02fad67dabp-106L, 0x3fb46641182f7efd9caa769dac0p-106L, 1.8804859395820231849002915747252695375405e-63L, 0.6404513901551516189871978418046651877394L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_c_c (clog10, 0x3e1d0a105ac4ebeacd9c6952d34cp-112L, 0xf859b3d1b06d005dcbb5516d5479p-112L, -5.0742964549782184008668435276046798273476e-67L, 0.5757527761596220360985719127090110408283L); + TEST_c_c (clog10, 0x47017a2e36807acb1e5214b209dep-112L, 0xf5f4a550c9d75e3bb1839d865f0dp-112L, 6.5482587585671294601662599808612773010057e-66L, 0.5601289501766423782280643144987875760229L); + TEST_c_c (clog10, 0x148f818cb7a9258fca942ade2a0cap-113L, 0x18854a34780b8333ec53310ad7001p-113L, -3.1210950417524756037077807411854181477733e-67L, 0.3791463562379872585396164879981280044658L); + TEST_c_c (clog10, 0xfd95243681c055c2632286921092p-113L, 0x1bccabcd29ca2152860ec29e34ef7p-113L, 2.8774482675253468630312378575186855052697e-66L, 0.4571561610046221605554903008571429975493L); + TEST_c_c (clog10, 0xdb85c467ee2aadd5f425fe0f4b8dp-114L, 0x3e83162a0f95f1dcbf97dddf410eap-114L, 1.9985076315737626043096596036300177494613e-67L, 0.5883569274304683249184005177865521205198L); + TEST_c_c (clog10, 0x1415bcaf2105940d49a636e98ae59p-115L, 0x7e6a150adfcd1b0921d44b31f40f4p-115L, 1.1288799405048268615023706955013387413519e-67L, 0.6137587762850841972073301550420510507903L); +#endif + END (clog10, complex); } @@ -4299,6 +4425,23 @@ fdim_test (void) static void +finite_test (void) +{ + START (finite); + + TEST_f_b (finite, 0, 1); + TEST_f_b (finite, minus_zero, 1); + TEST_f_b (finite, 10, 1); + TEST_f_b (finite, min_subnorm_value, 1); + TEST_f_b (finite, plus_infty, 0); + TEST_f_b (finite, minus_infty, 0); + TEST_f_b (finite, nan_value, 0); + + END (finite); +} + + +static void floor_test (void) { START (floor); @@ -4439,6 +4582,45 @@ fma_test (void) TEST_fff_f (fma, minus_infty, minus_infty, plus_infty, plus_infty); TEST_fff_f (fma, plus_infty, minus_infty, minus_infty, minus_infty); + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero); + + TEST_fff_f (fma, min_value, min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION); + #if defined (TEST_FLOAT) && FLT_MANT_DIG == 24 TEST_fff_f (fma, 0x1.7ff8p+13, 0x1.000002p+0, 0x1.ffffp-24, 0x1.7ff802p+13); TEST_fff_f (fma, 0x1.fffp+0, 0x1.00001p+0, -0x1.fffp+0, 0x1.fffp-20); @@ -4501,6 +4683,174 @@ fma_test (void) static void +fma_test_towardzero (void) +{ + int save_round_mode; + START (fma_towardzero); + + save_round_mode = fegetround (); + + if (!fesetround (FE_TOWARDZERO)) + { + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero); + + TEST_fff_f (fma, min_value, min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION); + } + + fesetround (save_round_mode); + + END (fma_towardzero); +} + + +static void +fma_test_downward (void) +{ + int save_round_mode; + START (fma_downward); + + save_round_mode = fegetround (); + + if (!fesetround (FE_DOWNWARD)) + { + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, minus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, minus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, minus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, minus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, minus_zero); + + TEST_fff_f (fma, min_value, min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, plus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, minus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, plus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, minus_zero, -min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, plus_zero, plus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, minus_zero, plus_zero, UNDERFLOW_EXCEPTION); + } + + fesetround (save_round_mode); + + END (fma_downward); +} + + +static void +fma_test_upward (void) +{ + int save_round_mode; + START (fma_upward); + + save_round_mode = fegetround (); + + if (!fesetround (FE_UPWARD)) + { + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero); + + TEST_fff_f (fma, min_value, min_value, plus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, min_value, minus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, min_value, -min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, plus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, min_value, minus_zero, minus_zero, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, plus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION); + TEST_fff_f (fma, -min_value, -min_value, minus_zero, min_subnorm_value, UNDERFLOW_EXCEPTION); + } + + fesetround (save_round_mode); + + END (fma_upward); +} + + +static void fmax_test (void) { START (fmax); @@ -4642,6 +4992,7 @@ fpclassify_test (void) TEST_f_i (fpclassify, plus_zero, FP_ZERO); TEST_f_i (fpclassify, minus_zero, FP_ZERO); TEST_f_i (fpclassify, 1000, FP_NORMAL); + TEST_f_i (fpclassify, min_subnorm_value, FP_SUBNORMAL); END (fpclassify); } @@ -4791,6 +5142,7 @@ isfinite_test (void) TEST_f_b (isfinite, 0, 1); TEST_f_b (isfinite, minus_zero, 1); TEST_f_b (isfinite, 10, 1); + TEST_f_b (isfinite, min_subnorm_value, 1); TEST_f_b (isfinite, plus_infty, 0); TEST_f_b (isfinite, minus_infty, 0); TEST_f_b (isfinite, nan_value, 0); @@ -4799,6 +5151,163 @@ isfinite_test (void) } static void +isgreater_test (void) +{ + START (isgreater); + + TEST_ff_i (isgreater, minus_zero, minus_zero, 0); + TEST_ff_i (isgreater, minus_zero, plus_zero, 0); + TEST_ff_i (isgreater, minus_zero, (FLOAT) 1, 0); + TEST_ff_i (isgreater, minus_zero, nan_value, 0); + TEST_ff_i (isgreater, plus_zero, minus_zero, 0); + TEST_ff_i (isgreater, plus_zero, plus_zero, 0); + TEST_ff_i (isgreater, plus_zero, (FLOAT) 1, 0); + TEST_ff_i (isgreater, plus_zero, nan_value, 0); + TEST_ff_i (isgreater, (FLOAT) 1, minus_zero, 1); + TEST_ff_i (isgreater, (FLOAT) 1, plus_zero, 1); + TEST_ff_i (isgreater, (FLOAT) 1, (FLOAT) 1, 0); + TEST_ff_i (isgreater, (FLOAT) 1, nan_value, 0); + TEST_ff_i (isgreater, nan_value, minus_zero, 0); + TEST_ff_i (isgreater, nan_value, plus_zero, 0); + TEST_ff_i (isgreater, nan_value, (FLOAT) 1, 0); + TEST_ff_i (isgreater, nan_value, nan_value, 0); + + END (isgreater); +} + +static void +isgreaterequal_test (void) +{ + START (isgreaterequal); + + TEST_ff_i (isgreaterequal, minus_zero, minus_zero, 1); + TEST_ff_i (isgreaterequal, minus_zero, plus_zero, 1); + TEST_ff_i (isgreaterequal, minus_zero, (FLOAT) 1, 0); + TEST_ff_i (isgreaterequal, minus_zero, nan_value, 0); + TEST_ff_i (isgreaterequal, plus_zero, minus_zero, 1); + TEST_ff_i (isgreaterequal, plus_zero, plus_zero, 1); + TEST_ff_i (isgreaterequal, plus_zero, (FLOAT) 1, 0); + TEST_ff_i (isgreaterequal, plus_zero, nan_value, 0); + TEST_ff_i (isgreaterequal, (FLOAT) 1, minus_zero, 1); + TEST_ff_i (isgreaterequal, (FLOAT) 1, plus_zero, 1); + TEST_ff_i (isgreaterequal, (FLOAT) 1, (FLOAT) 1, 1); + TEST_ff_i (isgreaterequal, (FLOAT) 1, nan_value, 0); + TEST_ff_i (isgreaterequal, nan_value, minus_zero, 0); + TEST_ff_i (isgreaterequal, nan_value, plus_zero, 0); + TEST_ff_i (isgreaterequal, nan_value, (FLOAT) 1, 0); + TEST_ff_i (isgreaterequal, nan_value, nan_value, 0); + + END (isgreaterequal); +} + +static void +isinf_test (void) +{ + START (isinf); + + TEST_f_b (isinf, 0, 0); + TEST_f_b (isinf, minus_zero, 0); + TEST_f_b (isinf, 10, 0); + TEST_f_b (isinf, min_subnorm_value, 0); + TEST_f_b (isinf, plus_infty, 1); + TEST_f_b (isinf, minus_infty, 1); + TEST_f_b (isinf, nan_value, 0); + + END (isinf); +} + +static void +isless_test (void) +{ + START (isless); + + TEST_ff_i (isless, minus_zero, minus_zero, 0); + TEST_ff_i (isless, minus_zero, plus_zero, 0); + TEST_ff_i (isless, minus_zero, (FLOAT) 1, 1); + TEST_ff_i (isless, minus_zero, nan_value, 0); + TEST_ff_i (isless, plus_zero, minus_zero, 0); + TEST_ff_i (isless, plus_zero, plus_zero, 0); + TEST_ff_i (isless, plus_zero, (FLOAT) 1, 1); + TEST_ff_i (isless, plus_zero, nan_value, 0); + TEST_ff_i (isless, (FLOAT) 1, minus_zero, 0); + TEST_ff_i (isless, (FLOAT) 1, plus_zero, 0); + TEST_ff_i (isless, (FLOAT) 1, (FLOAT) 1, 0); + TEST_ff_i (isless, (FLOAT) 1, nan_value, 0); + TEST_ff_i (isless, nan_value, minus_zero, 0); + TEST_ff_i (isless, nan_value, plus_zero, 0); + TEST_ff_i (isless, nan_value, (FLOAT) 1, 0); + TEST_ff_i (isless, nan_value, nan_value, 0); + + END (isless); +} + +static void +islessequal_test (void) +{ + START (islessequal); + + TEST_ff_i (islessequal, minus_zero, minus_zero, 1); + TEST_ff_i (islessequal, minus_zero, plus_zero, 1); + TEST_ff_i (islessequal, minus_zero, (FLOAT) 1, 1); + TEST_ff_i (islessequal, minus_zero, nan_value, 0); + TEST_ff_i (islessequal, plus_zero, minus_zero, 1); + TEST_ff_i (islessequal, plus_zero, plus_zero, 1); + TEST_ff_i (islessequal, plus_zero, (FLOAT) 1, 1); + TEST_ff_i (islessequal, plus_zero, nan_value, 0); + TEST_ff_i (islessequal, (FLOAT) 1, minus_zero, 0); + TEST_ff_i (islessequal, (FLOAT) 1, plus_zero, 0); + TEST_ff_i (islessequal, (FLOAT) 1, (FLOAT) 1, 1); + TEST_ff_i (islessequal, (FLOAT) 1, nan_value, 0); + TEST_ff_i (islessequal, nan_value, minus_zero, 0); + TEST_ff_i (islessequal, nan_value, plus_zero, 0); + TEST_ff_i (islessequal, nan_value, (FLOAT) 1, 0); + TEST_ff_i (islessequal, nan_value, nan_value, 0); + + END (islessequal); +} + +static void +islessgreater_test (void) +{ + START (islessgreater); + + TEST_ff_i (islessgreater, minus_zero, minus_zero, 0); + TEST_ff_i (islessgreater, minus_zero, plus_zero, 0); + TEST_ff_i (islessgreater, minus_zero, (FLOAT) 1, 1); + TEST_ff_i (islessgreater, minus_zero, nan_value, 0); + TEST_ff_i (islessgreater, plus_zero, minus_zero, 0); + TEST_ff_i (islessgreater, plus_zero, plus_zero, 0); + TEST_ff_i (islessgreater, plus_zero, (FLOAT) 1, 1); + TEST_ff_i (islessgreater, plus_zero, nan_value, 0); + TEST_ff_i (islessgreater, (FLOAT) 1, minus_zero, 1); + TEST_ff_i (islessgreater, (FLOAT) 1, plus_zero, 1); + TEST_ff_i (islessgreater, (FLOAT) 1, (FLOAT) 1, 0); + TEST_ff_i (islessgreater, (FLOAT) 1, nan_value, 0); + TEST_ff_i (islessgreater, nan_value, minus_zero, 0); + TEST_ff_i (islessgreater, nan_value, plus_zero, 0); + TEST_ff_i (islessgreater, nan_value, (FLOAT) 1, 0); + TEST_ff_i (islessgreater, nan_value, nan_value, 0); + + END (islessgreater); +} + +static void +isnan_test (void) +{ + START (isnan); + + TEST_f_b (isnan, 0, 0); + TEST_f_b (isnan, minus_zero, 0); + TEST_f_b (isnan, 10, 0); + TEST_f_b (isnan, min_subnorm_value, 0); + TEST_f_b (isnan, plus_infty, 0); + TEST_f_b (isnan, minus_infty, 0); + TEST_f_b (isnan, nan_value, 1); + + END (isnan); +} + +static void isnormal_test (void) { START (isnormal); @@ -4806,6 +5315,7 @@ isnormal_test (void) TEST_f_b (isnormal, 0, 0); TEST_f_b (isnormal, minus_zero, 0); TEST_f_b (isnormal, 10, 1); + TEST_f_b (isnormal, min_subnorm_value, 0); TEST_f_b (isnormal, plus_infty, 0); TEST_f_b (isnormal, minus_infty, 0); TEST_f_b (isnormal, nan_value, 0); @@ -4814,6 +5324,31 @@ isnormal_test (void) } static void +isunordered_test (void) +{ + START (isunordered); + + TEST_ff_i (isunordered, minus_zero, minus_zero, 0); + TEST_ff_i (isunordered, minus_zero, plus_zero, 0); + TEST_ff_i (isunordered, minus_zero, (FLOAT) 1, 0); + TEST_ff_i (isunordered, minus_zero, nan_value, 1); + TEST_ff_i (isunordered, plus_zero, minus_zero, 0); + TEST_ff_i (isunordered, plus_zero, plus_zero, 0); + TEST_ff_i (isunordered, plus_zero, (FLOAT) 1, 0); + TEST_ff_i (isunordered, plus_zero, nan_value, 1); + TEST_ff_i (isunordered, (FLOAT) 1, minus_zero, 0); + TEST_ff_i (isunordered, (FLOAT) 1, plus_zero, 0); + TEST_ff_i (isunordered, (FLOAT) 1, (FLOAT) 1, 0); + TEST_ff_i (isunordered, (FLOAT) 1, nan_value, 1); + TEST_ff_i (isunordered, nan_value, minus_zero, 1); + TEST_ff_i (isunordered, nan_value, plus_zero, 1); + TEST_ff_i (isunordered, nan_value, (FLOAT) 1, 1); + TEST_ff_i (isunordered, nan_value, nan_value, 1); + + END (isunordered); +} + +static void j0_test (void) { FLOAT s, c; @@ -9153,6 +9688,12 @@ initialize (void) LDBL_MAX, DBL_MAX, FLT_MAX); min_value = CHOOSE (LDBL_MIN, DBL_MIN, FLT_MIN, LDBL_MIN, DBL_MIN, FLT_MIN); + min_subnorm_value = CHOOSE (__LDBL_DENORM_MIN__, + __DBL_DENORM_MIN__, + __FLT_DENORM_MIN__, + __LDBL_DENORM_MIN__, + __DBL_DENORM_MIN__, + __FLT_DENORM_MIN__); (void) &plus_zero; (void) &nan_value; @@ -9161,6 +9702,7 @@ initialize (void) (void) &minus_infty; (void) &max_value; (void) &min_value; + (void) &min_subnorm_value; /* Clear all exceptions. From now on we must not get random exceptions. */ feclearexcept (FE_ALL_EXCEPT); @@ -9298,8 +9840,11 @@ main (int argc, char **argv) /* Keep the tests a wee bit ordered (according to ISO C99). */ /* Classification macros: */ + finite_test (); fpclassify_test (); isfinite_test (); + isinf_test (); + isnan_test (); isnormal_test (); signbit_test (); @@ -9432,6 +9977,17 @@ main (int argc, char **argv) /* Multiply and add: */ fma_test (); + fma_test_towardzero (); + fma_test_downward (); + fma_test_upward (); + + /* Comparison macros: */ + isgreater_test (); + isgreaterequal_test (); + isless_test (); + islessequal_test (); + islessgreater_test (); + isunordered_test (); /* Complex functions: */ cabs_test (); diff --git a/libc/math/s_ccosh.c b/libc/math/s_ccosh.c index 44c994446..91477ee2d 100644 --- a/libc/math/s_ccosh.c +++ b/libc/math/s_ccosh.c @@ -39,7 +39,15 @@ __ccosh (__complex__ double x) const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2); double sinix, cosix; - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (fabs (__real__ x) > t) { @@ -92,7 +100,15 @@ __ccosh (__complex__ double x) /* Imaginary part is finite. */ double sinix, cosix; - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } __real__ retval = __copysign (HUGE_VAL, cosix); __imag__ retval = (__copysign (HUGE_VAL, sinix) diff --git a/libc/math/s_ccoshf.c b/libc/math/s_ccoshf.c index d6f811049..9ca57b25b 100644 --- a/libc/math/s_ccoshf.c +++ b/libc/math/s_ccoshf.c @@ -39,7 +39,15 @@ __ccoshf (__complex__ float x) const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2); float sinix, cosix; - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } if (fabsf (__real__ x) > t) { @@ -92,7 +100,15 @@ __ccoshf (__complex__ float x) /* Imaginary part is finite. */ float sinix, cosix; - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } __real__ retval = __copysignf (HUGE_VALF, cosix); __imag__ retval = (__copysignf (HUGE_VALF, sinix) diff --git a/libc/math/s_ccoshl.c b/libc/math/s_ccoshl.c index 77a9ae386..1d561b4e3 100644 --- a/libc/math/s_ccoshl.c +++ b/libc/math/s_ccoshl.c @@ -39,7 +39,15 @@ __ccoshl (__complex__ long double x) const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l); long double sinix, cosix; - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (fabsl (__real__ x) > t) { @@ -92,7 +100,15 @@ __ccoshl (__complex__ long double x) /* Imaginary part is finite. */ long double sinix, cosix; - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } __real__ retval = __copysignl (HUGE_VALL, cosix); __imag__ retval = (__copysignl (HUGE_VALL, sinix) diff --git a/libc/math/s_cexp.c b/libc/math/s_cexp.c index 1d7a5a2c4..d0a95ba79 100644 --- a/libc/math/s_cexp.c +++ b/libc/math/s_cexp.c @@ -39,7 +39,15 @@ __cexp (__complex__ double x) const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2); double sinix, cosix; - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (__real__ x > t) { @@ -95,7 +103,15 @@ __cexp (__complex__ double x) { double sinix, cosix; - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } __real__ retval = __copysign (value, cosix); __imag__ retval = __copysign (value, sinix); diff --git a/libc/math/s_cexpf.c b/libc/math/s_cexpf.c index 4aa976581..41fcea51d 100644 --- a/libc/math/s_cexpf.c +++ b/libc/math/s_cexpf.c @@ -39,7 +39,15 @@ __cexpf (__complex__ float x) const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2); float sinix, cosix; - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } if (__real__ x > t) { @@ -95,7 +103,15 @@ __cexpf (__complex__ float x) { float sinix, cosix; - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } __real__ retval = __copysignf (value, cosix); __imag__ retval = __copysignf (value, sinix); diff --git a/libc/math/s_cexpl.c b/libc/math/s_cexpl.c index 256824924..d67cc5e5e 100644 --- a/libc/math/s_cexpl.c +++ b/libc/math/s_cexpl.c @@ -39,7 +39,15 @@ __cexpl (__complex__ long double x) const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l); long double sinix, cosix; - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (__real__ x > t) { @@ -95,7 +103,15 @@ __cexpl (__complex__ long double x) { long double sinix, cosix; - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } __real__ retval = __copysignl (value, cosix); __imag__ retval = __copysignl (value, sinix); diff --git a/libc/math/s_clog.c b/libc/math/s_clog.c index 259306600..79b1f375d 100644 --- a/libc/math/s_clog.c +++ b/libc/math/s_clog.c @@ -85,6 +85,19 @@ __clog (__complex__ double x) d2m1 += absy * absy; __real__ result = __log1p (d2m1) / 2.0; } + else if (absx < 1.0 + && absx >= 0.75 + && absy < DBL_EPSILON / 2.0 + && scale == 0) + { + double d2m1 = (absx - 1.0) * (absx + 1.0); + __real__ result = __log1p (d2m1) / 2.0; + } + else if (absx < 1.0 && (absx >= 0.75 || absy >= 0.5) && scale == 0) + { + double d2m1 = __x2y2m1 (absx, absy); + __real__ result = __log1p (d2m1) / 2.0; + } else { double d = __ieee754_hypot (absx, absy); diff --git a/libc/math/s_clog10.c b/libc/math/s_clog10.c index ef997ee76..4ccb5bcaa 100644 --- a/libc/math/s_clog10.c +++ b/libc/math/s_clog10.c @@ -88,6 +88,19 @@ __clog10 (__complex__ double x) d2m1 += absy * absy; __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0); } + else if (absx < 1.0 + && absx >= 0.75 + && absy < DBL_EPSILON / 2.0 + && scale == 0) + { + double d2m1 = (absx - 1.0) * (absx + 1.0); + __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0); + } + else if (absx < 1.0 && (absx >= 0.75 || absy >= 0.5) && scale == 0) + { + double d2m1 = __x2y2m1 (absx, absy); + __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0); + } else { double d = __ieee754_hypot (absx, absy); diff --git a/libc/math/s_clog10f.c b/libc/math/s_clog10f.c index c61e8af8c..1789f1aed 100644 --- a/libc/math/s_clog10f.c +++ b/libc/math/s_clog10f.c @@ -90,6 +90,19 @@ __clog10f (__complex__ float x) d2m1 += absy * absy; __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f); } + else if (absx < 1.0f + && absx >= 0.75f + && absy < FLT_EPSILON / 2.0f + && scale == 0) + { + float d2m1 = (absx - 1.0f) * (absx + 1.0f); + __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f); + } + else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0) + { + float d2m1 = __x2y2m1f (absx, absy); + __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f); + } else { float d = __ieee754_hypotf (absx, absy); diff --git a/libc/math/s_clog10l.c b/libc/math/s_clog10l.c index d50f61657..958f74abd 100644 --- a/libc/math/s_clog10l.c +++ b/libc/math/s_clog10l.c @@ -89,6 +89,19 @@ __clog10l (__complex__ long double x) d2m1 += absy * absy; __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L); } + else if (absx < 1.0L + && absx >= 0.75L + && absy < LDBL_EPSILON / 2.0L + && scale == 0) + { + long double d2m1 = (absx - 1.0L) * (absx + 1.0L); + __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L); + } + else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0) + { + long double d2m1 = __x2y2m1l (absx, absy); + __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L); + } else { long double d = __ieee754_hypotl (absx, absy); diff --git a/libc/math/s_clogf.c b/libc/math/s_clogf.c index 92f782c47..2b9038b41 100644 --- a/libc/math/s_clogf.c +++ b/libc/math/s_clogf.c @@ -85,6 +85,19 @@ __clogf (__complex__ float x) d2m1 += absy * absy; __real__ result = __log1pf (d2m1) / 2.0f; } + else if (absx < 1.0f + && absx >= 0.75f + && absy < FLT_EPSILON / 2.0f + && scale == 0) + { + float d2m1 = (absx - 1.0f) * (absx + 1.0f); + __real__ result = __log1pf (d2m1) / 2.0f; + } + else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0) + { + float d2m1 = __x2y2m1f (absx, absy); + __real__ result = __log1pf (d2m1) / 2.0f; + } else { float d = __ieee754_hypotf (absx, absy); diff --git a/libc/math/s_clogl.c b/libc/math/s_clogl.c index eaba572ce..af3ed9971 100644 --- a/libc/math/s_clogl.c +++ b/libc/math/s_clogl.c @@ -85,6 +85,19 @@ __clogl (__complex__ long double x) d2m1 += absy * absy; __real__ result = __log1pl (d2m1) / 2.0L; } + else if (absx < 1.0L + && absx >= 0.75L + && absy < LDBL_EPSILON / 2.0L + && scale == 0) + { + long double d2m1 = (absx - 1.0L) * (absx + 1.0L); + __real__ result = __log1pl (d2m1) / 2.0L; + } + else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0) + { + long double d2m1 = __x2y2m1l (absx, absy); + __real__ result = __log1pl (d2m1) / 2.0L; + } else { long double d = __ieee754_hypotl (absx, absy); diff --git a/libc/math/s_csin.c b/libc/math/s_csin.c index 602c14e53..725989c9c 100644 --- a/libc/math/s_csin.c +++ b/libc/math/s_csin.c @@ -42,7 +42,15 @@ __csin (__complex__ double x) const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2); double sinix, cosix; - __sincos (__real__ x, &sinix, &cosix); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincos (__real__ x, &sinix, &cosix); + } + else + { + sinix = __real__ x; + cosix = 1.0; + } if (fabs (__imag__ x) > t) { @@ -115,7 +123,15 @@ __csin (__complex__ double x) /* Real part is finite. */ double sinix, cosix; - __sincos (__real__ x, &sinix, &cosix); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincos (__real__ x, &sinix, &cosix); + } + else + { + sinix = __real__ x; + cosix = 1.0; + } __real__ retval = __copysign (HUGE_VAL, sinix); __imag__ retval = __copysign (HUGE_VAL, cosix); diff --git a/libc/math/s_csinf.c b/libc/math/s_csinf.c index c1d6a4f28..d53f943fa 100644 --- a/libc/math/s_csinf.c +++ b/libc/math/s_csinf.c @@ -42,7 +42,15 @@ __csinf (__complex__ float x) const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2); float sinix, cosix; - __sincosf (__real__ x, &sinix, &cosix); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincosf (__real__ x, &sinix, &cosix); + } + else + { + sinix = __real__ x; + cosix = 1.0f; + } if (fabsf (__imag__ x) > t) { @@ -115,7 +123,15 @@ __csinf (__complex__ float x) /* Real part is finite. */ float sinix, cosix; - __sincosf (__real__ x, &sinix, &cosix); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincosf (__real__ x, &sinix, &cosix); + } + else + { + sinix = __real__ x; + cosix = 1.0f; + } __real__ retval = __copysignf (HUGE_VALF, sinix); __imag__ retval = __copysignf (HUGE_VALF, cosix); diff --git a/libc/math/s_csinh.c b/libc/math/s_csinh.c index 56bb25623..20edbd13f 100644 --- a/libc/math/s_csinh.c +++ b/libc/math/s_csinh.c @@ -42,7 +42,15 @@ __csinh (__complex__ double x) const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2); double sinix, cosix; - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (fabs (__real__ x) > t) { @@ -109,7 +117,15 @@ __csinh (__complex__ double x) /* Imaginary part is finite. */ double sinix, cosix; - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } __real__ retval = __copysign (HUGE_VAL, cosix); __imag__ retval = __copysign (HUGE_VAL, sinix); diff --git a/libc/math/s_csinhf.c b/libc/math/s_csinhf.c index ba85e79b8..4b019a0ed 100644 --- a/libc/math/s_csinhf.c +++ b/libc/math/s_csinhf.c @@ -42,7 +42,15 @@ __csinhf (__complex__ float x) const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2); float sinix, cosix; - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } if (fabsf (__real__ x) > t) { @@ -109,7 +117,15 @@ __csinhf (__complex__ float x) /* Imaginary part is finite. */ float sinix, cosix; - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } __real__ retval = __copysignf (HUGE_VALF, cosix); __imag__ retval = __copysignf (HUGE_VALF, sinix); diff --git a/libc/math/s_csinhl.c b/libc/math/s_csinhl.c index e482e3a62..d9a928a40 100644 --- a/libc/math/s_csinhl.c +++ b/libc/math/s_csinhl.c @@ -42,7 +42,15 @@ __csinhl (__complex__ long double x) const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l); long double sinix, cosix; - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (fabsl (__real__ x) > t) { @@ -109,7 +117,15 @@ __csinhl (__complex__ long double x) /* Imaginary part is finite. */ long double sinix, cosix; - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } __real__ retval = __copysignl (HUGE_VALL, cosix); __imag__ retval = __copysignl (HUGE_VALL, sinix); diff --git a/libc/math/s_csinl.c b/libc/math/s_csinl.c index ff43256e5..9812bddd5 100644 --- a/libc/math/s_csinl.c +++ b/libc/math/s_csinl.c @@ -42,7 +42,15 @@ __csinl (__complex__ long double x) const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l); long double sinix, cosix; - __sincosl (__real__ x, &sinix, &cosix); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincosl (__real__ x, &sinix, &cosix); + } + else + { + sinix = __real__ x; + cosix = 1.0; + } if (fabsl (__imag__ x) > t) { @@ -115,7 +123,15 @@ __csinl (__complex__ long double x) /* Real part is finite. */ long double sinix, cosix; - __sincosl (__real__ x, &sinix, &cosix); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincosl (__real__ x, &sinix, &cosix); + } + else + { + sinix = __real__ x; + cosix = 1.0; + } __real__ retval = __copysignl (HUGE_VALL, sinix); __imag__ retval = __copysignl (HUGE_VALL, cosix); diff --git a/libc/math/s_ctan.c b/libc/math/s_ctan.c index 89c0fef91..fdba84744 100644 --- a/libc/math/s_ctan.c +++ b/libc/math/s_ctan.c @@ -53,11 +53,20 @@ __ctan (__complex__ double x) double sinrx, cosrx; double den; const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2 / 2); + int rcls = fpclassify (__real__ x); /* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y)) = (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */ - __sincos (__real__ x, &sinrx, &cosrx); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincos (__real__ x, &sinrx, &cosrx); + } + else + { + sinrx = __real__ x; + cosrx = 1.0; + } if (fabs (__imag__ x) > t) { diff --git a/libc/math/s_ctanf.c b/libc/math/s_ctanf.c index 2559f83f8..fd2b79788 100644 --- a/libc/math/s_ctanf.c +++ b/libc/math/s_ctanf.c @@ -57,7 +57,15 @@ __ctanf (__complex__ float x) /* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y)) = (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */ - __sincosf (__real__ x, &sinrx, &cosrx); + if (__builtin_expect (fpclassify(__real__ x) != FP_SUBNORMAL, 1)) + { + __sincosf (__real__ x, &sinrx, &cosrx); + } + else + { + sinrx = __real__ x; + cosrx = 1.0f; + } if (fabsf (__imag__ x) > t) { diff --git a/libc/math/s_ctanh.c b/libc/math/s_ctanh.c index d288b7d16..fee191055 100644 --- a/libc/math/s_ctanh.c +++ b/libc/math/s_ctanh.c @@ -53,11 +53,20 @@ __ctanh (__complex__ double x) double sinix, cosix; double den; const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2 / 2); + int icls = fpclassify (__imag__ x); /* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y)) = (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2). */ - __sincos (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincos (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (fabs (__real__ x) > t) { diff --git a/libc/math/s_ctanhf.c b/libc/math/s_ctanhf.c index ca36a83bf..862845f8c 100644 --- a/libc/math/s_ctanhf.c +++ b/libc/math/s_ctanhf.c @@ -57,7 +57,15 @@ __ctanhf (__complex__ float x) /* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y)) = (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2). */ - __sincosf (__imag__ x, &sinix, &cosix); + if (__builtin_expect (fpclassify(__imag__ x) != FP_SUBNORMAL, 1)) + { + __sincosf (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0f; + } if (fabsf (__real__ x) > t) { diff --git a/libc/math/s_ctanhl.c b/libc/math/s_ctanhl.c index dbf161270..c4fc1d3d0 100644 --- a/libc/math/s_ctanhl.c +++ b/libc/math/s_ctanhl.c @@ -53,11 +53,20 @@ __ctanhl (__complex__ long double x) long double sinix, cosix; long double den; const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l / 2); + int icls = fpclassify (__imag__ x); /* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y)) = (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2). */ - __sincosl (__imag__ x, &sinix, &cosix); + if (__builtin_expect (icls != FP_SUBNORMAL, 1)) + { + __sincosl (__imag__ x, &sinix, &cosix); + } + else + { + sinix = __imag__ x; + cosix = 1.0; + } if (fabsl (__real__ x) > t) { diff --git a/libc/math/s_ctanl.c b/libc/math/s_ctanl.c index 4fe26119c..0affe9321 100644 --- a/libc/math/s_ctanl.c +++ b/libc/math/s_ctanl.c @@ -53,11 +53,20 @@ __ctanl (__complex__ long double x) long double sinrx, cosrx; long double den; const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l / 2); + int rcls = fpclassify (__real__ x); /* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y)) = (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */ - __sincosl (__real__ x, &sinrx, &cosrx); + if (__builtin_expect (rcls != FP_SUBNORMAL, 1)) + { + __sincosl (__real__ x, &sinrx, &cosrx); + } + else + { + sinrx = __real__ x; + cosrx = 1.0; + } if (fabsl (__imag__ x) > t) { diff --git a/libc/misc/Versions b/libc/misc/Versions index 7f525eaf5..b2a91473d 100644 --- a/libc/misc/Versions +++ b/libc/misc/Versions @@ -149,4 +149,7 @@ libc { GLIBC_2.16 { __getauxval; getauxval; } + GLIBC_PRIVATE { + __madvise; + } } diff --git a/libc/misc/madvise.c b/libc/misc/madvise.c index 8f1c873c0..4e9681a52 100644 --- a/libc/misc/madvise.c +++ b/libc/misc/madvise.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1994,1995,1996,1997,2000,2007 Free Software Foundation, Inc. +/* Advise system about intentions for a memory region. Stub version. + Copyright (C) 1994-2012 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 @@ -23,11 +24,13 @@ for the region starting at ADDR and extending LEN bytes. */ int -madvise (__ptr_t addr, size_t len, int advice) +__madvise (void *addr, size_t len, int advice) { __set_errno (ENOSYS); return -1; } -libc_hidden_def (madvise) +libc_hidden_def (__madvise) +weak_alias (__madvise, madvise) + stub_warning (madvise) #include <stub-tag.h> diff --git a/libc/misc/sys/cdefs.h b/libc/misc/sys/cdefs.h index b94147efe..fb6c959d9 100644 --- a/libc/misc/sys/cdefs.h +++ b/libc/misc/sys/cdefs.h @@ -320,7 +320,7 @@ /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 inline semantics, unless -fgnu89-inline is used. */ -#if !defined __cplusplus || __GNUC_PREREQ (4,3) +#if (!defined __cplusplus || __GNUC_PREREQ (4,3)) && defined __GNUC__ # if defined __GNUC_STDC_INLINE__ || defined __cplusplus # define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) # define __extern_always_inline \ @@ -329,6 +329,13 @@ # define __extern_inline extern __inline # define __extern_always_inline extern __always_inline # endif +#elif defined __GNUC__ /* C++ and GCC <4.3. */ +# define __extern_inline extern __inline +# define __extern_always_inline \ + extern __always_inline +#else /* Not GCC. */ +# define __extern_inline /* Ignore */ +# define __extern_always_inline /* Ignore */ #endif /* GCC 4.3 and above allow passing all anonymous arguments of an diff --git a/libc/nis/yp_xdr.c b/libc/nis/yp_xdr.c index 76e0f2f21..418850643 100644 --- a/libc/nis/yp_xdr.c +++ b/libc/nis/yp_xdr.c @@ -49,21 +49,21 @@ libnsl_hidden_def (xdr_ypxfrstat) bool_t xdr_domainname (XDR *xdrs, domainname *objp) { - return xdr_string (xdrs, objp, ~0); + return xdr_string (xdrs, objp, YPMAXDOMAIN); } libnsl_hidden_def (xdr_domainname) bool_t xdr_mapname (XDR *xdrs, mapname *objp) { - return xdr_string (xdrs, objp, ~0); + return xdr_string (xdrs, objp, YPMAXMAP); } libnsl_hidden_def (xdr_mapname) bool_t xdr_peername (XDR *xdrs, peername *objp) { - return xdr_string (xdrs, objp, ~0); + return xdr_string (xdrs, objp, YPMAXPEER); } libnsl_hidden_def (xdr_peername) @@ -71,7 +71,7 @@ bool_t xdr_keydat (XDR *xdrs, keydat *objp) { return xdr_bytes (xdrs, (char **) &objp->keydat_val, - (u_int *) &objp->keydat_len, ~0); + (u_int *) &objp->keydat_len, YPMAXRECORD); } libnsl_hidden_def (xdr_keydat) @@ -79,7 +79,7 @@ bool_t xdr_valdat (XDR *xdrs, valdat *objp) { return xdr_bytes (xdrs, (char **) &objp->valdat_val, - (u_int *) &objp->valdat_len, ~0); + (u_int *) &objp->valdat_len, YPMAXRECORD); } libnsl_hidden_def (xdr_valdat) diff --git a/libc/nptl/ChangeLog b/libc/nptl/ChangeLog index 217693250..9eeeeb1bd 100644 --- a/libc/nptl/ChangeLog +++ b/libc/nptl/ChangeLog @@ -1,3 +1,84 @@ +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * sysdeps/pthread/configure: Regenerated. + * sysdeps/x86_64/configure: Regenerated. + +2012-10-05 David S. Miller <davem@davemloft.net> + + [BZ #14568] + * sysdeps/sparc/tls.h (DB_THREAD_SELF_INCLUDE): Delete. + (DB_THREAD_SELF): Use constants for the register offsets. Correct + the case of a 64-bit debugger with a 32-bit inferior. + +2012-10-05 H.J. Lu <hongjiu.lu@intel.com> + + [BZ #14557] + * Makefile (tests-static): Add tst-cancel24-static, + tst-cond8-static tst-mutex8-static, tst-mutexpi8-static, + tst-sem11-static and tst-sem12-static. + (tests): Likewise. + (LDLIBS-tst-cancel24-static): New macro. + * tst-cancel24-static.cc: New file. + * tst-cond8-static.c: Likewise. + * tst-mutex8-static.c: Likewise. + * tst-mutexpi8-static.c: Likewise. + * tst-sem11-static.c: Likewise. + * tst-sem12-static.c: Likewise. + +2012-10-05 Siddhesh Poyarekar <siddhesh@redhat.com> + + [BZ #14417] + * Makefile (tests): New test case tst-cond24. + (LDFLAGS-tst-cond24): Link tst-cond24 against librt. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S + (__pthread_cond_timedwait): Unlock mutex before going back to + wait in PI case. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S + (__pthread_cond_wait): Likewise. Revert handling of EAGAIN + return from futex_wait. + * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S + (__pthread_cond_timedwait): Unlock mutex before going back to + wait in PI case. Set requeue_pi flag only if wait returned 0. + * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S + (__pthread_cond_wait): Likewise. Revert handling of EAGAIN + return from futex_wait. + * tst-cond24.c: New test case. + +2012-10-04 Roland McGrath <roland@hack.frob.com> + + * pthread_create.c (start_thread): Use __madvise, not madvise. + +2012-10-02 H.J. Lu <hongjiu.lu@intel.com> + + * sysdeps/i386/tls.h: Update copyright years. + +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * pthread_create.c (start_thread): Fix clone flag name in + comment to CLONE_CHILD_CLEARTID. + * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise. + +2012-10-01 Siddhesh Poyarekar <siddhesh@redhat.com> + + [BZ #14477] + * Makefile (tests): Add tst-cond-except. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S + (__pthread_cond_timedwait): Mark instructions where %ebx is + incremented in PI case. + (.gcc_except_table): Add entry to jump to __condvar_tw_cleanup2 + for the marked PI case instructions. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S + (__pthread_cond_wait): Mark instructions where %ebx is + incremented in PI case. + (.gcc_except_table): Add entry to jump to __condvar_w_cleanup2 + for the marked PI case instructions. + * tst-cond-except.c: New test case. + 2012-09-24 Dmitry V. Levin <ldv@altlinux.org> * tst-tls6.sh: Add "set -e". diff --git a/libc/nptl/Makefile b/libc/nptl/Makefile index 5d781e206..47752f090 100644 --- a/libc/nptl/Makefile +++ b/libc/nptl/Makefile @@ -210,7 +210,8 @@ tests = tst-typesizes \ tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \ tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ - tst-cond20 tst-cond21 tst-cond22 tst-cond23 \ + tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 \ + tst-cond-except \ tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \ tst-robust6 tst-robust7 tst-robust8 tst-robust9 \ tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \ @@ -288,6 +289,7 @@ gen-as-const-headers = pthread-errnos.sym LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst +LDFLAGS-tst-cond24 = -lrt include ../Makeconfig @@ -368,8 +370,12 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \ $(common-objpfx)libc.a tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \ - tst-cancel21-static -tests += tst-stackguard1-static tst-cancel21-static + tst-cancel21-static tst-cancel24-static tst-cond8-static \ + tst-mutex8-static tst-mutexpi8-static tst-sem11-static \ + tst-sem12-static +tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \ + tst-cond8-static tst-mutex8-static tst-mutexpi8-static \ + tst-sem11-static tst-sem12-static xtests-static += tst-setuid1-static # These tests are linked with libc before libpthread @@ -528,6 +534,7 @@ $(objpfx)tst-rwlock14: $(common-objpfx)rt/librt.a endif LDLIBS-tst-cancel24 = $(no-as-needed) -lstdc++ +LDLIBS-tst-cancel24-static = $(LDLIBS-tst-cancel24) extra-B-pthread.so = -B$(common-objpfx)nptl/ $(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs)) diff --git a/libc/nptl/pthread_create.c b/libc/nptl/pthread_create.c index 96ca51f4e..44181ea39 100644 --- a/libc/nptl/pthread_create.c +++ b/libc/nptl/pthread_create.c @@ -404,7 +404,7 @@ start_thread (void *arg) #endif assert (freesize < pd->stackblock_size); if (freesize > PTHREAD_STACK_MIN) - madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED); + __madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED); /* If the thread is detached free the TCB. */ if (IS_DETACHED (pd)) @@ -425,7 +425,7 @@ start_thread (void *arg) /* We cannot call '_exit' here. '_exit' will terminate the process. The 'exit' implementation in the kernel will signal when the - process is really dead since 'clone' got passed the CLONE_CLEARTID + process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID flag. The 'tid' field in the TCB will be set to zero. The exit code is zero since in case all threads exit by calling diff --git a/libc/nptl/sysdeps/i386/tls.h b/libc/nptl/sysdeps/i386/tls.h index 65497cf92..eb1ca312f 100644 --- a/libc/nptl/sysdeps/i386/tls.h +++ b/libc/nptl/sysdeps/i386/tls.h @@ -1,5 +1,5 @@ /* Definition for thread-local data handling. nptl/i386 version. - Copyright (C) 2002-2007, 2009, 2011 Free Software Foundation, Inc. + Copyright (C) 2002-2012 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 diff --git a/libc/nptl/sysdeps/pthread/configure b/libc/nptl/sysdeps/pthread/configure index 221ce9bbb..7962ed6fc 100755 --- a/libc/nptl/sysdeps/pthread/configure +++ b/libc/nptl/sysdeps/pthread/configure @@ -1,123 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile # This file is generated from configure.in by Autoconf. DO NOT EDIT! if test "x$libc_cv_gcc___thread" != xyes; then diff --git a/libc/nptl/sysdeps/sparc/tls.h b/libc/nptl/sysdeps/sparc/tls.h index 61cb09f29..cfc9d96c6 100644 --- a/libc/nptl/sysdeps/sparc/tls.h +++ b/libc/nptl/sysdeps/sparc/tls.h @@ -117,9 +117,9 @@ register struct pthread *__thread_self __asm__("%g7"); #define THREAD_SELF __thread_self /* Magic for libthread_db to know how to do THREAD_SELF. */ -# define DB_THREAD_SELF_INCLUDE <sys/ucontext.h> # define DB_THREAD_SELF \ - REGISTER (32, 32, REG_G7 * 4, 0) REGISTER (64, 64, REG_G7 * 8, 0) + REGISTER (32, 32, 10 * 4, 0) \ + REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0) /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) \ diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S index 5f1fd5ddc..6761c136e 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S +++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S @@ -200,9 +200,11 @@ __pthread_cond_timedwait: 42: leal (%ebp), %esi movl 28(%esp), %edx addl $cond_futex, %ebx +.Ladd_cond_futex_pi: movl $SYS_futex, %eax ENTER_KERNEL subl $cond_futex, %ebx +.Lsub_cond_futex_pi: movl %eax, %esi /* Set the pi-requeued flag only if the kernel has returned 0. The kernel does not hold the mutex on ETIMEDOUT or any other error. */ @@ -210,8 +212,23 @@ __pthread_cond_timedwait: sete 24(%esp) je 41f - /* Normal and PI futexes dont mix. Use normal futex functions only - if the kernel does not support the PI futex functions. */ + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns + successfully, it has already locked the mutex for us and the + pi_flag (24(%esp)) is set to denote that fact. However, if another + thread changed the futex value before we entered the wait, the + syscall may return an EAGAIN and the mutex is not locked. We go + ahead with a success anyway since later we look at the pi_flag to + decide if we got the mutex or not. The sequence numbers then make + sure that only one of the threads actually wake up. We retry using + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal + and PI futexes don't mix. + + Note that we don't check for EAGAIN specifically; we assume that the + only other error the futex function could return is EAGAIN (barring + the ETIMEOUT of course, for the timeout case in futex) since + anything else would mean an error in our function. It is too + expensive to do that check for every call (which is quite common in + case of a large number of threads), so it has been skipped. */ cmpl $-ENOSYS, %eax jne 41f xorl %ecx, %ecx @@ -271,9 +288,24 @@ __pthread_cond_timedwait: jne 9f 15: cmpl $-ETIMEDOUT, %esi - jne 8b + je 28f + + /* We need to go back to futex_wait. If we're using requeue_pi, then + release the mutex we had acquired and go back. */ + movl 24(%esp), %edx + test %edx, %edx + jz 8b + + /* Adjust the mutex values first and then unlock it. The unlock + should always succeed or else the kernel did not lock the mutex + correctly. */ + movl dep_mutex(%ebx), %eax + call __pthread_mutex_cond_lock_adjust + xorl %edx, %edx + call __pthread_mutex_unlock_usercnt + jmp 8b - addl $1, wakeup_seq(%ebx) +28: addl $1, wakeup_seq(%ebx) adcl $0, wakeup_seq+4(%ebx) addl $1, cond_futex(%ebx) movl $ETIMEDOUT, %esi @@ -638,7 +670,15 @@ __condvar_tw_cleanup: .uleb128 .Lcstend-.Lcstbegin .Lcstbegin: .long .LcleanupSTART-.LSTARTCODE - .long .Ladd_cond_futex-.LcleanupSTART + .long .Ladd_cond_futex_pi-.LcleanupSTART + .long __condvar_tw_cleanup-.LSTARTCODE + .uleb128 0 + .long .Ladd_cond_futex_pi-.LSTARTCODE + .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi + .long __condvar_tw_cleanup2-.LSTARTCODE + .uleb128 0 + .long .Lsub_cond_futex_pi-.LSTARTCODE + .long .Ladd_cond_futex-.Lsub_cond_futex_pi .long __condvar_tw_cleanup-.LSTARTCODE .uleb128 0 .long .Ladd_cond_futex-.LSTARTCODE diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S index 2ae7af261..0af06acad 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S +++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S @@ -136,25 +136,37 @@ __pthread_cond_wait: cmpl $PI_BIT, %eax jne 18f -90: movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx movl %ebp, %edx xorl %esi, %esi addl $cond_futex, %ebx +.Ladd_cond_futex_pi: movl $SYS_futex, %eax ENTER_KERNEL subl $cond_futex, %ebx +.Lsub_cond_futex_pi: /* Set the pi-requeued flag only if the kernel has returned 0. The kernel does not hold the mutex on error. */ cmpl $0, %eax sete 16(%esp) je 19f - cmpl $-EAGAIN, %eax - je 91f - - /* Normal and PI futexes dont mix. Use normal futex functions only - if the kernel does not support the PI futex functions. */ + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns + successfully, it has already locked the mutex for us and the + pi_flag (16(%esp)) is set to denote that fact. However, if another + thread changed the futex value before we entered the wait, the + syscall may return an EAGAIN and the mutex is not locked. We go + ahead with a success anyway since later we look at the pi_flag to + decide if we got the mutex or not. The sequence numbers then make + sure that only one of the threads actually wake up. We retry using + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal + and PI futexes don't mix. + + Note that we don't check for EAGAIN specifically; we assume that the + only other error the futex function could return is EAGAIN since + anything else would mean an error in our function. It is too + expensive to do that check for every call (which is quite common in + case of a large number of threads), so it has been skipped. */ cmpl $-ENOSYS, %eax jne 19f xorl %ecx, %ecx @@ -204,12 +216,12 @@ __pthread_cond_wait: cmpl 8(%esp), %edx jne 7f cmpl 4(%esp), %edi - je 8b + je 22f 7: cmpl %ecx, %edx jne 9f cmp %eax, %edi - je 8b + je 22f 9: addl $1, woken_seq(%ebx) adcl $0, woken_seq+4(%ebx) @@ -285,6 +297,22 @@ __pthread_cond_wait: jmp 20b cfi_adjust_cfa_offset(-FRAME_SIZE); + + /* We need to go back to futex_wait. If we're using requeue_pi, then + release the mutex we had acquired and go back. */ +22: movl 16(%esp), %edx + test %edx, %edx + jz 8b + + /* Adjust the mutex values first and then unlock it. The unlock + should always succeed or else the kernel did not lock the mutex + correctly. */ + movl dep_mutex(%ebx), %eax + call __pthread_mutex_cond_lock_adjust + xorl %edx, %edx + call __pthread_mutex_unlock_usercnt + jmp 8b + /* Initial locking failed. */ 1: #if cond_lock == 0 @@ -398,77 +426,6 @@ __pthread_cond_wait: call __lll_unlock_wake jmp 11b -91: -.LcleanupSTART2: - /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to - call it again. */ - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jz 92f - -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - -92: - /* Increment the cond_futex value again, so it can be used as a new - expected value. */ - addl $1, cond_futex(%ebx) - movl cond_futex(%ebx), %ebp - - /* Unlock. */ - LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - je 93f -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - -93: - /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */ - xorl %ecx, %ecx - movl dep_mutex(%ebx), %edi - jmp 90b -.LcleanupEND2: - .size __pthread_cond_wait, .-__pthread_cond_wait versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, GLIBC_2_3_2) @@ -630,7 +587,15 @@ __condvar_w_cleanup: .uleb128 .Lcstend-.Lcstbegin .Lcstbegin: .long .LcleanupSTART-.LSTARTCODE - .long .Ladd_cond_futex-.LcleanupSTART + .long .Ladd_cond_futex_pi-.LcleanupSTART + .long __condvar_w_cleanup-.LSTARTCODE + .uleb128 0 + .long .Ladd_cond_futex_pi-.LSTARTCODE + .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi + .long __condvar_w_cleanup2-.LSTARTCODE + .uleb128 0 + .long .Lsub_cond_futex_pi-.LSTARTCODE + .long .Ladd_cond_futex-.Lsub_cond_futex_pi .long __condvar_w_cleanup-.LSTARTCODE .uleb128 0 .long .Ladd_cond_futex-.LSTARTCODE @@ -641,10 +606,6 @@ __condvar_w_cleanup: .long .LcleanupEND-.Lsub_cond_futex .long __condvar_w_cleanup-.LSTARTCODE .uleb128 0 - .long .LcleanupSTART2-.LSTARTCODE - .long .LcleanupEND2-.LcleanupSTART2 - .long __condvar_w_cleanup-.LSTARTCODE - .uleb128 0 .long .LcallUR-.LSTARTCODE .long .LENDCODE-.LcallUR .long 0 diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h index 3d805ff43..7b576ca00 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -544,7 +544,7 @@ LLL_STUB_UNWIND_INFO_END #define lll_islocked(futex) \ (futex != LLL_LOCK_INITIALIZER) -/* The kernel notifies a process with uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. diff --git a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h index 234e04234..406c290d7 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -288,7 +288,7 @@ extern int __lll_robust_timedlock_wait 1 - taken by one user >1 - taken by more users */ -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c index 4e3d7bd49..52ab53f0a 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c +++ b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c @@ -28,6 +28,7 @@ clear_once_control (void *arg) { pthread_once_t *once_control = (pthread_once_t *) arg; + __asm __volatile (__lll_rel_instr); *once_control = 0; lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); } @@ -47,15 +48,15 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) oldval = *once_control; if ((oldval & 2) == 0) *once_control = newval; - Do this atomically. + Do this atomically with an acquire barrier. */ newval = __fork_generation | 1; - __asm __volatile ("1: lwarx %0,0,%3\n" + __asm __volatile ("1: lwarx %0,0,%3" MUTEX_HINT_ACQ "\n" " andi. %1,%0,2\n" " bne 2f\n" " stwcx. %4,0,%3\n" " bne 1b\n" - "2: isync" + "2: " __lll_acq_instr : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control) : "r" (once_control), "r" (newval), "m" (*once_control) : "cr0"); @@ -87,8 +88,18 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) pthread_cleanup_pop (0); - /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */ - atomic_increment (once_control); + /* Add one to *once_control to take the bottom 2 bits from 01 to 10. + A release barrier is needed to ensure memory written by init_routine + is seen in other threads before *once_control changes. */ + int tmp; + __asm __volatile (__lll_rel_instr "\n" + "1: lwarx %0,0,%2" MUTEX_HINT_REL "\n" + " addi %0,%0,1\n" + " stwcx. %0,0,%2\n" + " bne- 1b" + : "=&b" (tmp), "=m" (*once_control) + : "r" (once_control), "m" (*once_control) + : "cr0"); /* Wake up all other threads. */ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); diff --git a/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h index eeb7a72e2..97092823d 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h @@ -329,7 +329,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime, #define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER_LOCKED (1) -/* The kernel notifies a process with uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h index f3ef3883a..cfd8d0cec 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h @@ -389,7 +389,7 @@ extern int __lll_unlock_wake (int *__futex, int private) attribute_hidden; #define lll_islocked(futex) \ (futex != LLL_LOCK_INITIALIZER) -/* The kernel notifies a process with uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h index 73c3327c0..fafb0873f 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h @@ -268,7 +268,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime, #define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER_LOCKED (1) -/* The kernel notifies a process with uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h index 3686970f0..5a80ddd8e 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -560,7 +560,7 @@ LLL_STUB_UNWIND_INFO_END (futex != LLL_LOCK_INITIALIZER) -/* The kernel notifies a process with uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S index a1c8ca87b..b669abb57 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S +++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S @@ -103,7 +103,7 @@ __pthread_cond_timedwait: mov %RSI_LP, dep_mutex(%rdi) 22: - xorl %r15d, %r15d + xorb %r15b, %r15b #ifndef __ASSUME_FUTEX_CLOCK_REALTIME # ifdef PIC @@ -190,18 +190,39 @@ __pthread_cond_timedwait: movl $SYS_futex, %eax syscall - movl $1, %r15d + cmpl $0, %eax + sete %r15b + #ifdef __ASSUME_REQUEUE_PI jmp 62f #else - cmpq $-4095, %rax - jnae 62f + je 62f + + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns + successfully, it has already locked the mutex for us and the + pi_flag (%r15b) is set to denote that fact. However, if another + thread changed the futex value before we entered the wait, the + syscall may return an EAGAIN and the mutex is not locked. We go + ahead with a success anyway since later we look at the pi_flag to + decide if we got the mutex or not. The sequence numbers then make + sure that only one of the threads actually wake up. We retry using + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal + and PI futexes don't mix. + + Note that we don't check for EAGAIN specifically; we assume that the + only other error the futex function could return is EAGAIN (barring + the ETIMEOUT of course, for the timeout case in futex) since + anything else would mean an error in our function. It is too + expensive to do that check for every call (which is quite common in + case of a large number of threads), so it has been skipped. */ + cmpl $-ENOSYS, %eax + jne 62f subq $cond_futex, %rdi #endif 61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi -60: xorl %r15d, %r15d +60: xorb %r15b, %r15b xorl %eax, %eax /* The following only works like this because we only support two clocks, represented using a single bit. */ @@ -248,7 +269,23 @@ __pthread_cond_timedwait: ja 39f 45: cmpq $-ETIMEDOUT, %r14 - jne 38b + je 99f + + /* We need to go back to futex_wait. If we're using requeue_pi, then + release the mutex we had acquired and go back. */ + test %r15b, %r15b + jz 38b + + /* Adjust the mutex values first and then unlock it. The unlock + should always succeed or else the kernel did not lock the + mutex correctly. */ + movq %r8, %rdi + callq __pthread_mutex_cond_lock_adjust + xorl %esi, %esi + callq __pthread_mutex_unlock_usercnt + /* Reload cond_var. */ + movq 8(%rsp), %rdi + jmp 38b 99: incq wakeup_seq(%rdi) incl cond_futex(%rdi) @@ -298,7 +335,7 @@ __pthread_cond_timedwait: /* If requeue_pi is used the kernel performs the locking of the mutex. */ 41: movq 16(%rsp), %rdi - testl %r15d, %r15d + testb %r15b, %r15b jnz 64f callq __pthread_mutex_cond_lock diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S index 61948523a..ec403cd9b 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S +++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S @@ -136,19 +136,36 @@ __pthread_cond_wait: cmpl $PI_BIT, %eax jne 61f -90: movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi movl $SYS_futex, %eax syscall - movl $1, %r8d - cmpq $-EAGAIN, %rax - je 91f + cmpl $0, %eax + sete %r8b + #ifdef __ASSUME_REQUEUE_PI jmp 62f #else - cmpq $-4095, %rax - jnae 62f + je 62f + + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns + successfully, it has already locked the mutex for us and the + pi_flag (%r8b) is set to denote that fact. However, if another + thread changed the futex value before we entered the wait, the + syscall may return an EAGAIN and the mutex is not locked. We go + ahead with a success anyway since later we look at the pi_flag to + decide if we got the mutex or not. The sequence numbers then make + sure that only one of the threads actually wake up. We retry using + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal + and PI futexes don't mix. + + Note that we don't check for EAGAIN specifically; we assume that the + only other error the futex function could return is EAGAIN since + anything else would mean an error in our function. It is too + expensive to do that check for every call (which is quite common in + case of a large number of threads), so it has been skipped. */ + cmpl $-ENOSYS, %eax + jne 62f # ifndef __ASSUME_PRIVATE_FUTEX movl $FUTEX_WAIT, %esi @@ -161,7 +178,7 @@ __pthread_cond_wait: #else orl %fs:PRIVATE_FUTEX, %esi #endif -60: xorl %r8d, %r8d +60: xorb %r8b, %r8b movl $SYS_futex, %eax syscall @@ -191,10 +208,10 @@ __pthread_cond_wait: jne 16f cmpq 24(%rsp), %r9 - jbe 8b + jbe 19f cmpq %rax, %r9 - jna 8b + jna 19f incq woken_seq(%rdi) @@ -236,7 +253,7 @@ __pthread_cond_wait: /* If requeue_pi is used the kernel performs the locking of the mutex. */ 11: movq 16(%rsp), %rdi - testl %r8d, %r8d + testb %r8b, %r8b jnz 18f callq __pthread_mutex_cond_lock @@ -253,6 +270,23 @@ __pthread_cond_wait: xorl %eax, %eax jmp 14b + /* We need to go back to futex_wait. If we're using requeue_pi, then + release the mutex we had acquired and go back. */ +19: testb %r8b, %r8b + jz 8b + + /* Adjust the mutex values first and then unlock it. The unlock + should always succeed or else the kernel did not lock the mutex + correctly. */ + movq 16(%rsp), %rdi + callq __pthread_mutex_cond_lock_adjust + movq %rdi, %r8 + xorl %esi, %esi + callq __pthread_mutex_unlock_usercnt + /* Reload cond_var. */ + movq 8(%rsp), %rdi + jmp 8b + /* Initial locking failed. */ 1: #if cond_lock != 0 @@ -331,69 +365,6 @@ __pthread_cond_wait: 13: movq %r10, %rax jmp 14b -91: -.LcleanupSTART2: - /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to - call it again. */ - movq 8(%rsp), %rdi - - /* Get internal lock. */ - movl $1, %esi - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %esi, (%rdi) -#else - cmpxchgl %esi, cond_lock(%rdi) -#endif - jz 92f - -#if cond_lock != 0 - addq $cond_lock, %rdi -#endif - LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi) - movl $LLL_PRIVATE, %eax - movl $LLL_SHARED, %esi - cmovne %eax, %esi - callq __lll_lock_wait -#if cond_lock != 0 - subq $cond_lock, %rdi -#endif -92: - /* Increment the cond_futex value again, so it can be used as a new - expected value. */ - incl cond_futex(%rdi) - movl cond_futex(%rdi), %edx - - /* Release internal lock. */ - LOCK -#if cond_lock == 0 - decl (%rdi) -#else - decl cond_lock(%rdi) -#endif - jz 93f - -#if cond_lock != 0 - addq $cond_lock, %rdi -#endif - LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi) - movl $LLL_PRIVATE, %eax - movl $LLL_SHARED, %esi - cmovne %eax, %esi - /* The call preserves %rdx. */ - callq __lll_unlock_wake -#if cond_lock != 0 - subq $cond_lock, %rdi -#endif -93: - /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */ - xorq %r10, %r10 - mov dep_mutex(%rdi), %R8_LP - leaq cond_futex(%rdi), %rdi - jmp 90b -.LcleanupEND2: - .size __pthread_cond_wait, .-__pthread_cond_wait versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, GLIBC_2_3_2) @@ -547,10 +518,6 @@ __condvar_cleanup1: .uleb128 .LcleanupEND-.LcleanupSTART .uleb128 __condvar_cleanup1-.LSTARTCODE .uleb128 0 - .uleb128 .LcleanupSTART2-.LSTARTCODE - .uleb128 .LcleanupEND2-.LcleanupSTART2 - .uleb128 __condvar_cleanup1-.LSTARTCODE - .uleb128 0 .uleb128 .LcallUR-.LSTARTCODE .uleb128 .LENDCODE-.LcallUR .uleb128 0 diff --git a/libc/nptl/sysdeps/x86_64/configure b/libc/nptl/sysdeps/x86_64/configure index ee047153c..8e5bcacaf 100644 --- a/libc/nptl/sysdeps/x86_64/configure +++ b/libc/nptl/sysdeps/x86_64/configure @@ -1,85 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/i386. diff --git a/libc/nptl/tst-cancel24-static.cc b/libc/nptl/tst-cancel24-static.cc new file mode 100644 index 000000000..3f97de5d5 --- /dev/null +++ b/libc/nptl/tst-cancel24-static.cc @@ -0,0 +1 @@ +#include "tst-cancel24.cc" diff --git a/libc/nptl/tst-cond-except.c b/libc/nptl/tst-cond-except.c new file mode 100644 index 000000000..b9871ba86 --- /dev/null +++ b/libc/nptl/tst-cond-except.c @@ -0,0 +1,108 @@ +/* Verify that exception table for pthread_cond_wait is correct. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +pthread_mutex_t mutex; +pthread_cond_t cond; + +#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \ + ({ if ((ret) != 0) \ + { \ + printf ("%s failed: %s\n", (str), strerror (ret)); \ + ret = 1; \ + goto out; \ + } \ + }) + + +void +clean (void *arg) +{ + puts ("clean: Unlocking mutex..."); + pthread_mutex_unlock ((pthread_mutex_t *) arg); + puts ("clean: Mutex unlocked..."); +} + +void * +thr (void *arg) +{ + int ret = 0; + pthread_mutexattr_t mutexAttr; + ret = pthread_mutexattr_init (&mutexAttr); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init"); + + ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol"); + + ret = pthread_mutex_init (&mutex, &mutexAttr); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init"); + + ret = pthread_cond_init (&cond, 0); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init"); + + puts ("th: Init done, entering wait..."); + + pthread_cleanup_push (clean, (void *) &mutex); + ret = pthread_mutex_lock (&mutex); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock"); + while (1) + { + ret = pthread_cond_wait (&cond, &mutex); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait"); + } + pthread_cleanup_pop (1); + +out: + return (void *)ret; +} + +int +do_test () +{ + pthread_t thread; + int ret = 0; + void *thr_ret = 0; + ret = pthread_create (&thread, 0, thr, &thr_ret); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create"); + + puts ("main: Thread created, waiting a bit..."); + sleep (2); + + puts ("main: Cancelling thread..."); + ret = pthread_cancel (thread); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel"); + + puts ("main: Joining th..."); + ret = pthread_join (thread, NULL); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join"); + + if (thr_ret != NULL) + return 1; + + puts ("main: Joined thread, done!"); + +out: + return ret; +} + +#define TIMEOUT 5 +#include "../test-skeleton.c" diff --git a/libc/nptl/tst-cond24.c b/libc/nptl/tst-cond24.c new file mode 100644 index 000000000..2eb2df1a3 --- /dev/null +++ b/libc/nptl/tst-cond24.c @@ -0,0 +1,249 @@ +/* Verify that condition variables synchronized by PI mutexes don't hang. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <sys/time.h> +#include <time.h> + +#define THREADS_NUM 5 +#define MAXITER 50000 + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mutex_attr; +static pthread_cond_t cond; +static pthread_t threads[THREADS_NUM]; +static int pending = 0; + +typedef void * (*threadfunc) (void *); + +void * +thread_fun_timed (void *arg) +{ + int *ret = arg; + int rv, i; + + printf ("Started thread_fun_timed[%d]\n", *ret); + + for (i = 0; i < MAXITER / THREADS_NUM; i++) + { + rv = pthread_mutex_lock (&mutex); + if (rv) + { + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + + while (!pending) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 20; + rv = pthread_cond_timedwait (&cond, &mutex, &ts); + + /* There should be no timeout either. */ + if (rv) + { + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + pending--; + + rv = pthread_mutex_unlock (&mutex); + if (rv) + { + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + *ret = 0; + +out: + return ret; +} + +void * +thread_fun (void *arg) +{ + int *ret = arg; + int rv, i; + + printf ("Started thread_fun[%d]\n", *ret); + + for (i = 0; i < MAXITER / THREADS_NUM; i++) + { + rv = pthread_mutex_lock (&mutex); + if (rv) + { + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + + while (!pending) + { + rv = pthread_cond_wait (&cond, &mutex); + + if (rv) + { + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + pending--; + + rv = pthread_mutex_unlock (&mutex); + if (rv) + { + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + *ret = 0; + +out: + return ret; +} + +static int +do_test_wait (threadfunc f) +{ + int i; + int rv; + int counter = 0; + int retval[THREADS_NUM]; + + puts ("Starting test"); + + rv = pthread_mutexattr_init (&mutex_attr); + if (rv) + { + printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT); + if (rv) + { + printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_mutex_init (&mutex, &mutex_attr); + if (rv) + { + printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_cond_init (&cond, NULL); + if (rv) + { + printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv); + return 1; + } + + for (i = 0; i < THREADS_NUM; i++) + { + retval[i] = i; + rv = pthread_create (&threads[i], NULL, f, &retval[i]); + if (rv) + { + printf ("pthread_create: %s(%d)\n", strerror (rv), rv); + return 1; + } + } + + for (; counter < MAXITER; counter++) + { + rv = pthread_mutex_lock (&mutex); + if (rv) + { + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); + return 1; + } + + if (!(counter % 100)) + printf ("counter: %d\n", counter); + pending += 1; + + rv = pthread_cond_signal (&cond); + if (rv) + { + printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_mutex_unlock (&mutex); + if (rv) + { + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); + return 1; + } + } + + for (i = 0; i < THREADS_NUM; i++) + { + void *ret; + rv = pthread_join (threads[i], &ret); + if (rv) + { + printf ("pthread_join: %s(%d)\n", strerror (rv), rv); + return 1; + } + if (ret && *(int *)ret) + { + printf ("Thread %d returned with an error\n", i); + return 1; + } + } + + return 0; +} + +static int +do_test (void) +{ + puts ("Testing pthread_cond_wait"); + int ret = do_test_wait (thread_fun); + if (ret) + return ret; + + puts ("Testing pthread_cond_timedwait"); + return do_test_wait (thread_fun_timed); +} + +#define TIMEOUT 10 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/libc/nptl/tst-cond8-static.c b/libc/nptl/tst-cond8-static.c new file mode 100644 index 000000000..fed35db60 --- /dev/null +++ b/libc/nptl/tst-cond8-static.c @@ -0,0 +1 @@ +#include "tst-cond8.c" diff --git a/libc/nptl/tst-mutex8-static.c b/libc/nptl/tst-mutex8-static.c new file mode 100644 index 000000000..d69ed49ad --- /dev/null +++ b/libc/nptl/tst-mutex8-static.c @@ -0,0 +1 @@ +#include "tst-mutex8.c" diff --git a/libc/nptl/tst-mutexpi8-static.c b/libc/nptl/tst-mutexpi8-static.c new file mode 100644 index 000000000..869e6df95 --- /dev/null +++ b/libc/nptl/tst-mutexpi8-static.c @@ -0,0 +1 @@ +#include "tst-mutexpi8.c" diff --git a/libc/nptl/tst-sem11-static.c b/libc/nptl/tst-sem11-static.c new file mode 100644 index 000000000..09b769807 --- /dev/null +++ b/libc/nptl/tst-sem11-static.c @@ -0,0 +1 @@ +#include "tst-sem11.c" diff --git a/libc/nptl/tst-sem12-static.c b/libc/nptl/tst-sem12-static.c new file mode 100644 index 000000000..c06349f2b --- /dev/null +++ b/libc/nptl/tst-sem12-static.c @@ -0,0 +1 @@ +#include "tst-sem12.c" diff --git a/libc/nptl_db/ChangeLog b/libc/nptl_db/ChangeLog index fe1778ee9..417514978 100644 --- a/libc/nptl_db/ChangeLog +++ b/libc/nptl_db/ChangeLog @@ -1,3 +1,9 @@ +2012-10-08 Jonathan Nieder <jrnieder@gmail.com> + + [BZ #14661] + * Makefile ($(objpfx)db-symbols.out): Force C locale when running + readelf -s. + 2012-03-07 Ulrich Drepper <drepper@gmail.com> * Makefile (distribute): Remove variable. diff --git a/libc/nptl_db/Makefile b/libc/nptl_db/Makefile index d15fb9e81..6ccb3d0cc 100644 --- a/libc/nptl_db/Makefile +++ b/libc/nptl_db/Makefile @@ -60,6 +60,6 @@ $(objpfx)libthread_db.so: $(common-objpfx)libc.so \ tests: $(objpfx)db-symbols.out $(objpfx)db-symbols.out: $(objpfx)db-symbols.v.i \ $(common-objpfx)nptl/libpthread.so - readelf -W -s $(filter %.so,$^) | $(AWK) -f $< > $@ + LC_ALL=C readelf -W -s $(filter %.so,$^) | $(AWK) -f $< > $@ $(objpfx)db-symbols.v.i: db-symbols.awk diff --git a/libc/nscd/Makefile b/libc/nscd/Makefile index bc2f94530..e4714ba6d 100644 --- a/libc/nscd/Makefile +++ b/libc/nscd/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1998,2000,2002-2009,2011,2012 Free Software Foundation, Inc. +# Copyright (C) 1998-2012 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 @@ -86,49 +86,21 @@ CFLAGS-nscd_gethst_r.c = -fexceptions CFLAGS-nscd_getai.c = -fexceptions CFLAGS-nscd_initgroups.c = -fexceptions -nscd-cflags = -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2 +CPPFLAGS-nonlib += -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2 + ifeq (yesyes,$(have-fpie)$(build-shared)) -nscd-cflags += $(pie-ccflag) +CFLAGS-nonlib += $(pie-ccflag) endif ifeq (yes,$(have-ssp)) -nscd-cflags += -fstack-protector +CFLAGS-nonlib += -fstack-protector endif -CFLAGS-nscd.c += $(nscd-cflags) -CFLAGS-connections.c += $(nscd-cflags) -CFLAGS-pwdcache.c += $(nscd-cflags) -CFLAGS-getpwnam_r.c += $(nscd-cflags) -CFLAGS-getpwuid_r.c += $(nscd-cflags) -CFLAGS-grpcache.c += $(nscd-cflags) -CFLAGS-getgrnam_r.c += $(nscd-cflags) -CFLAGS-getgrgid_r.c += $(nscd-cflags) -CFLAGS-hstcache.c += $(nscd-cflags) -CFLAGS-gethstbyad_r.c += $(nscd-cflags) -CFLAGS-gethstbynm3_r.c += $(nscd-cflags) -CFLAGS-dbg_log.c += $(nscd-cflags) -CFLAGS-nscd_conf.c += $(nscd-cflags) -CFLAGS-nscd_stat.c += $(nscd-cflags) -CFLAGS-cache.c += $(nscd-cflags) -CFLAGS-xmalloc.c += $(nscd-cflags) -CFLAGS-xstrdup.c += $(nscd-cflags) -CFLAGS-mem.c += $(nscd-cflags) -CFLAGS-nscd_setup_thread.c += $(nscd-cflags) -CFLAGS-aicache.c += $(nscd-cflags) -CFLAGS-selinux.c += $(nscd-cflags) -CFLAGS-initgrcache.c += $(nscd-cflags) -CFLAGS-gai.c += $(nscd-cflags) -CFLAGS-servicescache.c += $(nscd-cflags) -CFLAGS-getsrvbynm_r.c += $(nscd-cflags) -CFLAGS-getsrvbypt_r.c += $(nscd-cflags) -CFLAGS-res_hconf.c += $(nscd-cflags) -CFLAGS-nis_hash.c += $(nscd-cflags) -CFLAGS-netgroupcache.c += $(nscd-cflags) - ifeq (yesyes,$(have-fpie)$(build-shared)) LDFLAGS-nscd = -Wl,-z,now endif -# This makes sure -DNOT_IN_libc is passed for all these modules. +# This makes sure CPPFLAGS-nonlib and CFLAGS-nonlib are passed +# for all these modules. cpp-srcs-left := $(nscd-modules:=.c) lib := nonlib include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) diff --git a/libc/nss/Makefile b/libc/nss/Makefile index dad1c9106..8fab79dd0 100644 --- a/libc/nss/Makefile +++ b/libc/nss/Makefile @@ -157,6 +157,8 @@ CFLAGS-nss_test1.c = -DNOT_IN_libc=1 $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(common-objpfx)libc.so \ $(common-objpfx)libc_nonshared.a $(build-module) +ifdef libnss_test1.so-version $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so $(make-link) +endif $(objpfx)tst-nss-test1.out: $(objpfx)/libnss_test1.so$(libnss_test1.so-version) diff --git a/libc/nss/nsswitch.c b/libc/nss/nsswitch.c index 929df5422..480110d5e 100644 --- a/libc/nss/nsswitch.c +++ b/libc/nss/nsswitch.c @@ -56,8 +56,10 @@ static name_database *nss_parse_file (const char *fname) internal_function; static name_database_entry *nss_getline (char *line) internal_function; static service_user *nss_parse_service_list (const char *line) internal_function; +#if !defined DO_STATIC_NSS || defined SHARED static service_library *nss_new_service (name_database *database, const char *name) internal_function; +#endif /* Declare external database variables. */ @@ -474,7 +476,9 @@ __nss_lookup_function (service_user *ni, const char *fct_name) known_function *known = malloc (sizeof *known); if (! known) { +#if !defined DO_STATIC_NSS || defined SHARED remove_from_tree: +#endif /* Oops. We can't instantiate this node properly. Remove it from the tree. */ __tdelete (&fct_name, &ni->known.tree, &known_compare); @@ -860,6 +864,7 @@ nss_getline (char *line) } +#if !defined DO_STATIC_NSS || defined SHARED static service_library * internal_function nss_new_service (name_database *database, const char *name) @@ -884,6 +889,7 @@ nss_new_service (name_database *database, const char *name) return *currentp; } +#endif #endif /* __OPTION_EGLIBC_NSSWITCH */ diff --git a/libc/ports/ChangeLog.alpha b/libc/ports/ChangeLog.alpha index ab807f7d4..8cddb777e 100644 --- a/libc/ports/ChangeLog.alpha +++ b/libc/ports/ChangeLog.alpha @@ -1,4 +1,35 @@ -2012-12-13 Richard Henderson <rth@redhat.com> +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * sysdeps/alpha/configure: Regenerated. + +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + +2012-10-01 Roland McGrath <roland@hack.frob.com> + + * sysdeps/unix/sysv/linux/alpha/bits/typesizes.h + (__SWBLK_T_TYPE): Macro removed. + +2012-09-28 Richard Henderson <rth@redhat.com> + + * sysdeps/unix/alpha/sysdep.h (PSEUDO_END): Merge versions and + move $syscall_error label... + (SYSCALL_ERROR_HANDLER): ... here. + (SYSCALL_ERROR_FALLTHRU): New. + (PSEUDO_PROF): Split out of ... + (PSEUDO_PROLOGUE): ... here. + * sysdeps/unix/sysv/linux/alpha/syscall.S (__syscall): Use + SYSCALL_ERROR_LABEL and PSEUDO_END. + * sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Likewise. + Use USEPV_PROF and cfi markup. + (thread_start): Use cfi markup and cfi_undefined on ra. + * sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h + (PSEUDO_PROF): Remove. + (PSEUDO): Use SYSCALL_ERROR_FALLTHRU. + +2012-09-13 Richard Henderson <rth@redhat.com> * sysdeps/unix/sysv/linux/alpha/setfpucw.c (__setfpucw): Rewrite with the assumption of being used at program startup only. diff --git a/libc/ports/ChangeLog.am33 b/libc/ports/ChangeLog.am33 index 7e644caae..e8243c532 100644 --- a/libc/ports/ChangeLog.am33 +++ b/libc/ports/ChangeLog.am33 @@ -1,3 +1,7 @@ +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * sysdeps/unix/sysv/linux/am33/configure: Regenerated. + 2012-08-07 Joseph Myers <joseph@codesourcery.com> * sysdeps/unix/sysv/linux/am33/configure.in (arch_minimum_kernel): diff --git a/libc/ports/ChangeLog.arm b/libc/ports/ChangeLog.arm index b6c022516..a45063082 100644 --- a/libc/ports/ChangeLog.arm +++ b/libc/ports/ChangeLog.arm @@ -1,3 +1,22 @@ +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * sysdeps/arm/configure: Regenerated. + +2012-10-05 Roland McGrath <roland@hack.frob.com> + + * sysdeps/arm/dl-machine.h (fix_bad_pc24): Rewritten, replaced with ... + (relocate_pc24): ... this new function. + (elf_machine_rel, elf_machine_rela): Update callers. + +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + +2012-09-28 H.J. Lu <hongjiu.lu@intel.com> + + * sysdeps/arm/dl-tlsdesc.h (ADDRIDX): Removed. + 2012-09-21 Joseph Myers <joseph@codesourcery.com> * sysdeps/arm/bits/atomic.h [!__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4] diff --git a/libc/ports/ChangeLog.hppa b/libc/ports/ChangeLog.hppa index d34d9c2d2..5b16146e4 100644 --- a/libc/ports/ChangeLog.hppa +++ b/libc/ports/ChangeLog.hppa @@ -1,3 +1,8 @@ +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + 2012-09-20 Carlos O'Donell <carlos@systemhalted.org> * sysdeps/unix/sysv/linux/hppa/syscalls.list: Use __prlimit64 as diff --git a/libc/ports/ChangeLog.ia64 b/libc/ports/ChangeLog.ia64 index 39ec5ffe7..641033b29 100644 --- a/libc/ports/ChangeLog.ia64 +++ b/libc/ports/ChangeLog.ia64 @@ -1,3 +1,12 @@ +2012-10-09 Roland McGrath <roland@hack.frob.com> + + * sysdeps/ia64/configure: Regenerated. + +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + 2012-09-24 Mike Frysinger <vapier@gentoo.org> * ports/sysdeps/ia64/fpu/fegetround.c (fegetround): Move contents diff --git a/libc/ports/ChangeLog.linux-generic b/libc/ports/ChangeLog.linux-generic index b5774de5f..efbf3992a 100644 --- a/libc/ports/ChangeLog.linux-generic +++ b/libc/ports/ChangeLog.linux-generic @@ -1,3 +1,8 @@ +2012-10-01 Roland McGrath <roland@hack.frob.com> + + * sysdeps/unix/sysv/linux/generic/bits/typesizes.h + (__SWBLK_T_TYPE): Macro removed. + 2012-08-02 Roland McGrath <roland@hack.frob.com> * sysdeps/unix/sysv/linux/generic/bits/typesizes.h diff --git a/libc/ports/ChangeLog.m68k b/libc/ports/ChangeLog.m68k index 5163cf3f7..e9b4f3689 100644 --- a/libc/ports/ChangeLog.m68k +++ b/libc/ports/ChangeLog.m68k @@ -1,3 +1,13 @@ +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + +2012-09-28 Roland McGrath <roland@hack.frob.com> + + * sysdeps/unix/sysv/linux/m68k/init-first.c: Include main file from + csu/ rather than sysdeps/unix/sysv/linux/. + 2012-08-27 Joseph Myers <joseph@codesourcery.com> * sysdeps/unix/sysv/linux/m68k/kernel-features.h diff --git a/libc/ports/ChangeLog.mips b/libc/ports/ChangeLog.mips index 8c41753e5..add9c2dd3 100644 --- a/libc/ports/ChangeLog.mips +++ b/libc/ports/ChangeLog.mips @@ -1,3 +1,25 @@ +2012-10-03 Steve Ellcey <sellcey@mips.com> + + * sysdeps/mips/ieee754.h: Move to... + * sysdeps/mips/ieee754/ieee754.h: Here. + * sysdeps/mips/mips32/Implies: Add mips/ieee754. + * sysdeps/mips/mips64/Implies: Ditto. + * sysdeps/mips/mips64/n32/Implies: Ditto. + * sysdeps/mips/mips64/n64/Implies: Ditto. + +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + +2012-09-28 Roland McGrath <roland@hack.frob.com> + + * sysdeps/mips/init-first.c: File removed. + +2012-09-28 H.J. Lu <hongjiu.lu@intel.com> + + * sysdeps/mips/dl-trampoline.c (VERSYMIDX): Removed. + 2012-08-27 Joseph Myers <joseph@codesourcery.com> * sysdeps/unix/sysv/linux/mips/kernel-features.h diff --git a/libc/ports/ChangeLog.powerpc b/libc/ports/ChangeLog.powerpc index af98f828e..aa5595602 100644 --- a/libc/ports/ChangeLog.powerpc +++ b/libc/ports/ChangeLog.powerpc @@ -1,3 +1,8 @@ +2012-09-26 Joseph Myers <joseph@codesourcery.com> + + * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist: + Add __ppc_get_timebase_freq. + 2012-09-12 Joseph Myers <joseph@codesourcery.com> * sysdeps/powerpc/nofpu/get-rounding-mode.h: New file. diff --git a/libc/ports/ChangeLog.tile b/libc/ports/ChangeLog.tile index e1d4c3c76..2d19358e7 100644 --- a/libc/ports/ChangeLog.tile +++ b/libc/ports/ChangeLog.tile @@ -1,3 +1,8 @@ +2012-10-02 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h: Fix clone + flag name in comment to CLONE_CHILD_CLEARTID. + 2012-09-17 Chris Metcalf <cmetcalf@tilera.com> * sysdeps/tile/libm-test-ulps: Account for new tests. diff --git a/libc/ports/sysdeps/alpha/configure b/libc/ports/sysdeps/alpha/configure index d906524bd..9c03229df 100644 --- a/libc/ports/sysdeps/alpha/configure +++ b/libc/ports/sysdeps/alpha/configure @@ -4,3 +4,4 @@ # With required gcc+binutils, we can always access static and hidden # symbols in a position independent way. $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + diff --git a/libc/ports/sysdeps/arm/configure b/libc/ports/sysdeps/arm/configure index 51fd72557..385f29590 100644 --- a/libc/ports/sysdeps/arm/configure +++ b/libc/ports/sysdeps/arm/configure @@ -1,102 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/arm. diff --git a/libc/ports/sysdeps/arm/dl-machine.h b/libc/ports/sysdeps/arm/dl-machine.h index 343a83e98..3b25e0f0f 100644 --- a/libc/ports/sysdeps/arm/dl-machine.h +++ b/libc/ports/sysdeps/arm/dl-machine.h @@ -302,36 +302,56 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, #define ARCH_LA_PLTEXIT arm_gnu_pltexit #ifdef RESOLVE_MAP - -/* Deal with an out-of-range PC24 reloc. */ -auto Elf32_Addr -fix_bad_pc24 (Elf32_Addr *const reloc_addr, Elf32_Addr value) +/* Handle a PC24 reloc, including the out-of-range case. */ +auto void +relocate_pc24 (struct link_map *map, Elf32_Addr value, + Elf32_Addr *const reloc_addr, Elf32_Sword addend) { - static void *fix_page; - static unsigned int fix_offset; - static size_t pagesize; - Elf32_Word *fix_address; + Elf32_Addr new_value; + + /* Set NEW_VALUE based on V, and return true iff it overflows 24 bits. */ + inline bool set_new_value (Elf32_Addr v) + { + new_value = v + addend - (Elf32_Addr) reloc_addr; + Elf32_Addr topbits = new_value & 0xfe000000; + return topbits != 0xfe000000 && topbits != 0x00000000; + } - if (! fix_page) + if (set_new_value (value)) { - if (! pagesize) - pagesize = getpagesize (); - fix_page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (! fix_page) - assert (! "could not map page for fixup"); - fix_offset = 0; + /* The PC-relative address doesn't fit in 24 bits! */ + + static void *fix_page; + static size_t fix_offset; + if (fix_page == NULL) + { + void *new_page = __mmap (NULL, GLRO(dl_pagesize), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (new_page == MAP_FAILED) + _dl_signal_error (0, map->l_name, NULL, + "could not map page for fixup"); + fix_page = new_page; + assert (fix_offset == 0); + } + + Elf32_Word *fix_address = fix_page + fix_offset; + fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */ + fix_address[1] = value; + + fix_offset += sizeof fix_address[0] * 2; + if (fix_offset >= GLRO(dl_pagesize)) + { + fix_page = NULL; + fix_offset = 0; + } + + if (set_new_value ((Elf32_Addr) fix_address)) + _dl_signal_error (0, map->l_name, NULL, + "R_ARM_PC24 relocation out of range"); } - fix_address = (Elf32_Word *)(fix_page + fix_offset); - fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */ - fix_address[1] = value; - - fix_offset += 8; - if (fix_offset >= pagesize) - fix_page = NULL; - - return (Elf32_Addr)fix_address; + *reloc_addr = (*reloc_addr & 0xff000000) | ((new_value >> 2) & 0x00ffffff); } /* Perform the relocation specified by RELOC and SYM (which is fully resolved). @@ -473,30 +493,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, } break; case R_ARM_PC24: - { - Elf32_Sword addend; - Elf32_Addr newvalue, topbits; - - addend = *reloc_addr & 0x00ffffff; - if (addend & 0x00800000) addend |= 0xff000000; - - newvalue = value - (Elf32_Addr)reloc_addr + (addend << 2); - topbits = newvalue & 0xfe000000; - if (topbits != 0xfe000000 && topbits != 0x00000000) - { - newvalue = fix_bad_pc24(reloc_addr, value) - - (Elf32_Addr)reloc_addr + (addend << 2); - topbits = newvalue & 0xfe000000; - if (topbits != 0xfe000000 && topbits != 0x00000000) - { - _dl_signal_error (0, map->l_name, NULL, - "R_ARM_PC24 relocation out of range"); - } - } - newvalue >>= 2; - value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff); - *reloc_addr = value; - } + relocate_pc24 (map, value, reloc_addr, + /* Sign-extend the 24-bit addend in the + instruction (which counts instructions), and + then shift it up two so as to count bytes. */ + (((Elf32_Sword) *reloc_addr << 8) >> 8) << 2); break; #if !defined RTLD_BOOTSTRAP case R_ARM_TLS_DTPMOD32: @@ -589,26 +590,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = value + reloc->r_addend; break; case R_ARM_PC24: - { - Elf32_Addr newvalue, topbits; - - newvalue = value + reloc->r_addend - (Elf32_Addr)reloc_addr; - topbits = newvalue & 0xfe000000; - if (topbits != 0xfe000000 && topbits != 0x00000000) - { - newvalue = fix_bad_pc24(reloc_addr, value) - - (Elf32_Addr)reloc_addr + (reloc->r_addend << 2); - topbits = newvalue & 0xfe000000; - if (topbits != 0xfe000000 && topbits != 0x00000000) - { - _dl_signal_error (0, map->l_name, NULL, - "R_ARM_PC24 relocation out of range"); - } - } - newvalue >>= 2; - value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff); - *reloc_addr = value; - } + relocate_pc24 (map, value, reloc_addr, reloc->r_addend); break; #if !defined RTLD_BOOTSTRAP case R_ARM_TLS_DTPMOD32: diff --git a/libc/ports/sysdeps/arm/dl-tlsdesc.h b/libc/ports/sysdeps/arm/dl-tlsdesc.h index 2b1131c55..97951c0da 100644 --- a/libc/ports/sysdeps/arm/dl-tlsdesc.h +++ b/libc/ports/sysdeps/arm/dl-tlsdesc.h @@ -20,12 +20,6 @@ #ifndef _ARM_DL_TLSDESC_H # define _ARM_DL_TLSDESC_H 1 -/* Use this to access DT_TLSDESC_PLT and DT_TLSDESC_GOT. */ -#ifndef ADDRIDX -# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag)) -#endif - /* Type used to represent a TLS descriptor in the GOT. */ struct tlsdesc { diff --git a/libc/ports/sysdeps/hppa/configure b/libc/ports/sysdeps/hppa/configure index c47fb6d0a..762b668f4 100644 --- a/libc/ports/sysdeps/hppa/configure +++ b/libc/ports/sysdeps/hppa/configure @@ -1,85 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler line separator" >&5 diff --git a/libc/ports/sysdeps/ia64/configure b/libc/ports/sysdeps/ia64/configure index d73346006..e1fe62d8c 100644 --- a/libc/ports/sysdeps/ia64/configure +++ b/libc/ports/sysdeps/ia64/configure @@ -1,89 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/ia64. diff --git a/libc/ports/sysdeps/mips/dl-trampoline.c b/libc/ports/sysdeps/mips/dl-trampoline.c index 3454eb306..e4886cc9b 100644 --- a/libc/ports/sysdeps/mips/dl-trampoline.c +++ b/libc/ports/sysdeps/mips/dl-trampoline.c @@ -112,8 +112,6 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) generated by the gnu linker. */ int _dl_mips_gnu_objects = 1; -#define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) - /* This is called from assembly stubs below which the compiler can't see. */ static ElfW(Addr) __dl_runtime_resolve (ElfW(Word), ElfW(Word), ElfW(Addr), ElfW(Addr)) diff --git a/libc/ports/sysdeps/mips/ieee754.h b/libc/ports/sysdeps/mips/ieee754/ieee754.h index 87dbf658e..87dbf658e 100644 --- a/libc/ports/sysdeps/mips/ieee754.h +++ b/libc/ports/sysdeps/mips/ieee754/ieee754.h diff --git a/libc/ports/sysdeps/mips/init-first.c b/libc/ports/sysdeps/mips/init-first.c deleted file mode 100644 index 6a5e7caf0..000000000 --- a/libc/ports/sysdeps/mips/init-first.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. For mips/Unix. - Copyright (C) 1996, 1997, 2010 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, see - <http://www.gnu.org/licenses/>. */ - -#include <unistd.h> - -extern void __libc_init (int, char **, char **); -extern void __libc_global_ctors (void); - - -static void -init (int *data) -{ - int argc = *data; - char **argv = (void *) (data + 1); - char **envp = &argv[argc + 1]; - - __environ = envp; - __libc_init (argc, argv, envp); -} - -#ifdef SHARED -/* This function is called to initialize the shared C library. - It is called just before the user _start code from mips/elf/start.S, - with the stack set up as that code gets it. */ - -/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT - pointer in the dynamic section based solely on that. It is convention - for this function to be in the `.init' section, but the symbol name is - the only thing that really matters!! */ -/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ - -void -_init (int argc, ...) -{ - init (&argc); - -#ifndef NO_CTORS_DTORS_SECTIONS - __libc_global_ctors (); -#endif -} -#endif - - -void -__libc_init_first (int argc __attribute__ ((unused)), ...) -{ -#ifndef SHARED - init (&argc); -#endif -} diff --git a/libc/ports/sysdeps/mips/mips32/Implies b/libc/ports/sysdeps/mips/mips32/Implies index fab98d731..6473f2517 100644 --- a/libc/ports/sysdeps/mips/mips32/Implies +++ b/libc/ports/sysdeps/mips/mips32/Implies @@ -1,2 +1,3 @@ +mips/ieee754 mips wordsize-32 diff --git a/libc/ports/sysdeps/mips/mips64/Implies b/libc/ports/sysdeps/mips/mips64/Implies index 8c18cb303..826ff1541 100644 --- a/libc/ports/sysdeps/mips/mips64/Implies +++ b/libc/ports/sysdeps/mips/mips64/Implies @@ -1,3 +1,4 @@ # MIPS uses IEEE 754 floating point. +mips/ieee754 ieee754/flt-32 ieee754/dbl-64 diff --git a/libc/ports/sysdeps/mips/mips64/n32/Implies b/libc/ports/sysdeps/mips/mips64/n32/Implies index bed8f14c3..9ab2f3261 100644 --- a/libc/ports/sysdeps/mips/mips64/n32/Implies +++ b/libc/ports/sysdeps/mips/mips64/n32/Implies @@ -1,3 +1,4 @@ +mips/ieee754 ieee754/ldbl-128 mips/mips64/soft-fp mips/mips64 diff --git a/libc/ports/sysdeps/mips/mips64/n64/Implies b/libc/ports/sysdeps/mips/mips64/n64/Implies index 214b85c77..de23ed1c3 100644 --- a/libc/ports/sysdeps/mips/mips64/n64/Implies +++ b/libc/ports/sysdeps/mips/mips64/n64/Implies @@ -1,3 +1,4 @@ +mips/ieee754 ieee754/ldbl-128 mips/mips64/soft-fp mips/mips64 diff --git a/libc/ports/sysdeps/unix/alpha/sysdep.h b/libc/ports/sysdeps/unix/alpha/sysdep.h index 4ee0746ac..75c06c9cf 100644 --- a/libc/ports/sysdeps/unix/alpha/sysdep.h +++ b/libc/ports/sysdeps/unix/alpha/sysdep.h @@ -52,13 +52,20 @@ #define END(sym) .end sym #ifdef PROF +# define PSEUDO_PROF \ + .set noat; \ + lda AT, _mcount; \ + jsr AT, (AT), _mcount; \ + .set at +#else +# define PSEUDO_PROF +#endif + +#ifdef PROF # define PSEUDO_PROLOGUE \ .frame sp, 0, ra; \ ldgp gp,0(pv); \ - .set noat; \ - lda AT,_mcount; \ - jsr AT,(AT),_mcount; \ - .set at; \ + PSEUDO_PROF; \ .prologue 1 #elif defined PIC # define PSEUDO_PROLOGUE \ @@ -80,16 +87,21 @@ #if RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_LABEL $syscall_error # define SYSCALL_ERROR_HANDLER \ +$syscall_error: \ stl v0, rtld_errno(gp) !gprel; \ lda v0, -1; \ ret +# define SYSCALL_ERROR_FALLTHRU #elif defined(PIC) -# define SYSCALL_ERROR_LABEL __syscall_error !samegp +# define SYSCALL_ERROR_LABEL __syscall_error !samegp # define SYSCALL_ERROR_HANDLER +# define SYSCALL_ERROR_FALLTHRU br SYSCALL_ERROR_LABEL #else -# define SYSCALL_ERROR_LABEL $syscall_error -# define SYSCALL_ERROR_HANDLER \ - jmp $31, __syscall_error +# define SYSCALL_ERROR_LABEL $syscall_error +# define SYSCALL_ERROR_HANDLER \ +$syscall_error: \ + jmp $31, __syscall_error +# define SYSCALL_ERROR_FALLTHRU #endif /* RTLD_PRIVATE_ERRNO */ /* Overridden by specific syscalls. */ @@ -108,14 +120,9 @@ __LABEL(name) \ bne a3, SYSCALL_ERROR_LABEL #undef PSEUDO_END -#if defined(PIC) && !RTLD_PRIVATE_ERRNO -# define PSEUDO_END(sym) END(sym) -#else -# define PSEUDO_END(sym) \ -$syscall_error: \ +#define PSEUDO_END(sym) \ SYSCALL_ERROR_HANDLER; \ END(sym) -#endif #define PSEUDO_NOERRNO(name, syscall_name, args) \ .globl name; \ diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h index 31258e420..5ab9ac43a 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h +++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h @@ -50,7 +50,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __S64_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SLONGWORD_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE void * diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S b/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S index 1c6c8d6b7..b92b6c2e7 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S +++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/clone.S @@ -35,89 +35,84 @@ we don't bother checking FLAGS. */ .text -ENTRY(__clone) + .align 4 + .globl __clone + .ent __clone + .usepv __clone, USEPV_PROF + + cfi_startproc +__clone: #ifdef PROF ldgp gp,0(pv) - .set noat lda AT, _mcount jsr AT, (AT), _mcount - .set at - .prologue 1 -#else - .prologue 0 #endif /* Sanity check arguments. */ - ldiq v0,EINVAL - beq a0,$error /* no NULL function pointers */ - beq a1,$error /* no NULL stack pointers */ + ldiq v0, EINVAL + beq a0, SYSCALL_ERROR_LABEL /* no NULL function pointers */ + beq a1, SYSCALL_ERROR_LABEL /* no NULL stack pointers */ /* Save the fn ptr and arg on the new stack. */ - subq a1,32,a1 - stq a0,0(a1) - stq a3,8(a1) + subq a1, 32, a1 + stq a0, 0(a1) + stq a3, 8(a1) #ifdef RESET_PID - stq a2,16(a1) + stq a2, 16(a1) #endif /* The syscall is of the form clone(flags, usp, ptid, ctid, tls). Shift the flags, ptid, ctid, tls arguments into place; the child_stack argument is already correct. */ - mov a2,a0 - mov a4,a2 - ldq a3,0(sp) - mov a5,a4 + mov a2, a0 + mov a4, a2 + ldq a3, 0(sp) + mov a5, a4 /* Do the system call. */ - ldiq v0,__NR_clone + ldiq v0, __NR_clone call_pal PAL_callsys - bne a3,$error - beq v0,thread_start + bne a3, SYSCALL_ERROR_LABEL + beq v0, thread_start /* Successful return from the parent. */ ret - /* Something bad happened -- no child created. */ -$error: -#ifndef PROF - br gp,1f -1: ldgp gp,0(gp) -#endif - SYSCALL_ERROR_HANDLER - - END(__clone) +PSEUDO_END(__clone) + cfi_endproc /* Load up the arguments to the function. Put this block of code in its own function so that we can terminate the stack trace with our debug info. */ .ent thread_start + cfi_startproc thread_start: - .frame fp,0,fp,0 mov 0, fp - .prologue 0 + cfi_def_cfa_register(fp) + cfi_undefined(ra) #ifdef RESET_PID /* Check and see if we need to reset the PID. */ - ldq t0,16(sp) - lda t1,CLONE_THREAD - and t0,t1,t2 - beq t2,2f + ldq t0, 16(sp) + lda t1, CLONE_THREAD + and t0, t1, t2 + beq t2, 2f 1: #endif /* Load up the arguments. */ - ldq pv,0(sp) - ldq a0,8(sp) - addq sp,32,sp + ldq pv, 0(sp) + ldq a0, 8(sp) + addq sp, 32, sp /* Call the user's function. */ - jsr ra,(pv) - ldgp gp,0(ra) + jsr ra, (pv) + ldgp gp, 0(ra) /* Call _exit rather than doing it inline for breakpoint purposes. */ - mov v0,a0 + mov v0, a0 #ifdef PIC bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp #else @@ -142,7 +137,7 @@ thread_start: stl v0, TID_OFFSET(s0) br 1b #endif - + cfi_endproc .end thread_start weak_alias (__clone, clone) diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h index ac364dae1..0ef2e7fd3 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h @@ -259,7 +259,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime, #define LLL_LOCK_INITIALIZER_LOCKED (1) -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h index 04c7af472..e6795d98f 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h @@ -23,16 +23,6 @@ #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt -# ifdef PROF -# define PSEUDO_PROF \ - .set noat; \ - lda AT, _mcount; \ - jsr AT, (AT), _mcount; \ - .set at -# else -# define PSEUDO_PROF -# endif - /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END besides "ret". */ @@ -88,7 +78,7 @@ __LABEL($multi_error) \ addq sp, 64, sp; \ cfi_restore(ra); \ cfi_def_cfa_offset(0); \ -__LABEL($syscall_error) \ + SYSCALL_ERROR_FALLTHRU; \ SYSCALL_ERROR_HANDLER; \ cfi_endproc; \ .previous diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S b/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S index 830b10acb..5cec3800e 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S +++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/syscall.S @@ -62,16 +62,9 @@ LEAF(__syscall, 0) ldq a5,0(sp) /* arg6 -> a5 */ call_pal PAL_callsys /* Invoke system call */ - bne a3, $error + bne a3, SYSCALL_ERROR_LABEL ret -$error: -#ifndef PROF - br gp, 2f -2: ldgp gp, 0(gp) -#endif - SYSCALL_ERROR_HANDLER - -END(__syscall) +PSEUDO_END(__syscall) weak_alias (__syscall, syscall) diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h index b9fa69ce3..5811361e3 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h @@ -256,7 +256,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, 1 - taken by one user >1 - taken by more users */ -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h b/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h index d7d2a5c10..d5799d185 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h +++ b/libc/ports/sysdeps/unix/sysv/linux/generic/bits/typesizes.h @@ -52,7 +52,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SLONGWORD_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE void * diff --git a/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h index 6d4b13517..ad601c683 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h @@ -319,7 +319,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime, extern int lll_unlock_wake_cb (lll_lock_t *__futex) attribute_hidden; -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h index 24ed47e22..e36ff2653 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h @@ -267,7 +267,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, #define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER_LOCKED (1) -/* The kernel notifies a process with uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c b/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c index ec311ec42..713ab86b1 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c +++ b/libc/ports/sysdeps/unix/sysv/linux/m68k/init-first.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 Free Software Foundation, Inc. +/* Initialization code run first thing by the ELF startup code. Linux/m68k. + Copyright (C) 2010-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010. @@ -70,4 +71,4 @@ _libc_vdso_platform_setup (void) #endif /* SHARED */ -#include <sysdeps/unix/sysv/linux/init-first.c> +#include <csu/init-first.c> diff --git a/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h index fed152ae3..4dbed8d37 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h @@ -254,7 +254,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, 1 - taken by one user >1 - taken by more users */ -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h index d368ae1b6..9c1701167 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h @@ -268,7 +268,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime, 1 - taken by one user >1 - taken by more users */ -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist b/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist index 11ad6a525..481162e99 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist +++ b/libc/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist @@ -1775,6 +1775,7 @@ GLIBC_2.16 GLIBC_2.17 GLIBC_2.17 A secure_getenv F + __ppc_get_timebase_freq F GLIBC_2.2 GLIBC_2.2 A _IO_adjust_wcolumn F diff --git a/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h b/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h index 8690c7be4..0e0d48ed0 100644 --- a/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h +++ b/libc/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h @@ -255,7 +255,7 @@ __lll_robust_timedlock (int *futex, const struct timespec *abstime, #define LLL_LOCK_INITIALIZER_LOCKED (1) -/* The kernel notifies a process which uses CLONE_CLEARTID via futex +/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ diff --git a/libc/posix/Makefile b/libc/posix/Makefile index 89f86bacf..e88f0ce22 100644 --- a/libc/posix/Makefile +++ b/libc/posix/Makefile @@ -159,6 +159,7 @@ endif # it will say by examining the system, and write the results in config-name.h. uname.c: $(objpfx)config-name.h $(objpfx)config-name.h: $(..)scripts/config-uname.sh $(common-objpfx)config.make + $(make-target-directory) $< '$(config-os)' '$(config-release)' \ '$(config-machine)-$(config-vendor)' > $@.new mv -f $@.new $@ diff --git a/libc/posix/gai.conf b/libc/posix/gai.conf index 195287e1c..4616ed005 100644 --- a/libc/posix/gai.conf +++ b/libc/posix/gai.conf @@ -55,23 +55,11 @@ # # scopev4 <mask> <value> -# Add another rule to the RFC 3484 scope table for IPv4 addresses. -# By default the scope IDs described in section 3.2 in RFC 3484 are +# Add another rule to the RFC 6724 scope table for IPv4 addresses. +# By default the scope IDs described in section 3.2 in RFC 6724 are # used. Changing these defaults should hardly ever be necessary. # The defaults are equivalent to: # #scopev4 ::ffff:169.254.0.0/112 2 #scopev4 ::ffff:127.0.0.0/104 2 -#scopev4 ::ffff:10.0.0.0/104 5 -#scopev4 ::ffff:172.16.0.0/108 5 -#scopev4 ::ffff:192.168.0.0/112 5 -#scopev4 ::ffff:0.0.0.0/96 14 -# -# For sites which use site-local IPv4 addresses behind NAT there is -# the problem that even if IPv4 addresses are preferred they do not -# have the same scope and are therefore not sorted first. To change -# this use only these rules: -# -#scopev4 ::ffff:169.254.0.0/112 2 -#scopev4 ::ffff:127.0.0.0/104 2 #scopev4 ::ffff:0.0.0.0/96 14 diff --git a/libc/posix/glob.c b/libc/posix/glob.c index b90943543..b82ba77e1 100644 --- a/libc/posix/glob.c +++ b/libc/posix/glob.c @@ -220,7 +220,7 @@ static int collated_compare (const void *, const void *) __THROW; static const char * next_brace_sub (const char *cp, int flags) { - unsigned int depth = 0; + size_t depth = 0; while (*cp != '\0') if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\') { @@ -965,7 +965,7 @@ glob (pattern, flags, errfunc, pglob) && S_ISDIR (st.st_mode)) : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode))))) { - int newcount = pglob->gl_pathc + pglob->gl_offs; + size_t newcount = pglob->gl_pathc + pglob->gl_offs; char **new_gl_pathv; if (newcount > UINTPTR_MAX - (1 + 1) @@ -1064,7 +1064,7 @@ glob (pattern, flags, errfunc, pglob) appending the results to PGLOB. */ for (i = 0; i < dirs.gl_pathc; ++i) { - int old_pathc; + size_t old_pathc; #ifdef SHELL { @@ -1119,7 +1119,7 @@ glob (pattern, flags, errfunc, pglob) /* No matches. */ if (flags & GLOB_NOCHECK) { - int newcount = pglob->gl_pathc + pglob->gl_offs; + size_t newcount = pglob->gl_pathc + pglob->gl_offs; char **new_gl_pathv; if (newcount > UINTPTR_MAX - 2 @@ -1163,7 +1163,7 @@ glob (pattern, flags, errfunc, pglob) } else { - int old_pathc = pglob->gl_pathc; + size_t old_pathc = pglob->gl_pathc; int orig_flags = flags; if (meta & 2) diff --git a/libc/posix/tst-rfc3484.c b/libc/posix/tst-rfc3484.c index 29e1461e1..db3ae1b7b 100644 --- a/libc/posix/tst-rfc3484.c +++ b/libc/posix/tst-rfc3484.c @@ -71,6 +71,9 @@ service_user *__nss_hosts_database attribute_hidden; struct sockaddr_in addrs[] = { + { .sin_family = AF_INET, .sin_addr = { h (0x0aa85f19) } }, + { .sin_family = AF_INET, .sin_addr = { h (0xac105f19) } }, + { .sin_family = AF_INET, .sin_addr = { h (0xc0000219) } }, { .sin_family = AF_INET, .sin_addr = { h (0xc0a86d1d) } }, { .sin_family = AF_INET, .sin_addr = { h (0xc0a85d03) } }, { .sin_family = AF_INET, .sin_addr = { h (0xc0a82c3d) } }, @@ -86,7 +89,7 @@ static size_t order[naddrs]; static int expected[naddrs] = { - 6, 1, 0, 3, 2, 4, 5 + 9, 4, 3, 6, 5, 7, 8, 2, 0, 1 }; diff --git a/libc/rt/tst-aio2.c b/libc/rt/tst-aio2.c index 897d37d8b..01a94fe27 100644 --- a/libc/rt/tst-aio2.c +++ b/libc/rt/tst-aio2.c @@ -1,5 +1,5 @@ /* Test for notification mechanism in lio_listio. - Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2000-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. @@ -23,6 +23,7 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> +#include <pthread.h> static pthread_barrier_t b; diff --git a/libc/rt/tst-aio3.c b/libc/rt/tst-aio3.c index 4d1fe8e97..133e386cd 100644 --- a/libc/rt/tst-aio3.c +++ b/libc/rt/tst-aio3.c @@ -1,5 +1,5 @@ /* Test for notification mechanism in lio_listio. - Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2000-2012 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 @@ -22,6 +22,7 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> +#include <pthread.h> static pthread_barrier_t b; diff --git a/libc/scripts/check-local-headers.sh b/libc/scripts/check-local-headers.sh index cacb842de..7fafcbf4d 100755 --- a/libc/scripts/check-local-headers.sh +++ b/libc/scripts/check-local-headers.sh @@ -31,7 +31,7 @@ exec ${AWK} -v includedir="$includedir" ' BEGIN { status = 0 exclude = "^" includedir \ - "/(.*-.*-.*/|)(asm[-/]|linux/|selinux/|gd|nss3/|sys/capability\\.h|libaudit\\.h)" + "/(.*-.*-.*/|)(asm[-/]|linux/|selinux/|gd|nss3/|sys/(capability|sdt(|-config))\\.h|libaudit\\.h)" } /^[^ ]/ && $1 ~ /.*:/ { obj = $1 } { diff --git a/libc/scripts/config.guess b/libc/scripts/config.guess index 49ba16f15..872b96a16 100755 --- a/libc/scripts/config.guess +++ b/libc/scripts/config.guess @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. -timestamp='2012-01-01' +timestamp='2012-09-25' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -17,9 +17,7 @@ timestamp='2012-01-01' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -202,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} @@ -304,7 +306,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -803,6 +805,9 @@ EOF i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; @@ -863,6 +868,13 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -1196,6 +1208,9 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1251,7 +1266,7 @@ EOF NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; - NSE-?:NONSTOP_KERNEL:*:*) + NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) @@ -1320,11 +1335,11 @@ EOF i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - eval $set_cc_for_build cat >$dummy.c <<EOF #ifdef _SEQUENT_ diff --git a/libc/scripts/config.sub b/libc/scripts/config.sub index b6f695a83..bdda9e4a3 100755 --- a/libc/scripts/config.sub +++ b/libc/scripts/config.sub @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. -timestamp='2012-01-28' +timestamp='2012-08-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -21,9 +21,7 @@ timestamp='2012-01-28' # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -125,7 +123,7 @@ esac maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) @@ -227,6 +225,12 @@ case $os in -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -251,6 +255,7 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ @@ -362,6 +367,7 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ @@ -785,6 +791,10 @@ case $basic_machine in microblaze) basic_machine=microblaze-xilinx ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; mingw32) basic_machine=i386-pc os=-mingw32 @@ -1346,15 +1356,15 @@ case $os in | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1537,6 +1547,9 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; + hexagon-*) + os=-elf + ;; tic54x-*) os=-coff ;; diff --git a/libc/stdio-common/Makefile b/libc/stdio-common/Makefile index 1e2c2b1cc..881eb9b2e 100644 --- a/libc/stdio-common/Makefile +++ b/libc/stdio-common/Makefile @@ -129,6 +129,7 @@ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ # We know the test has a format string problem. CFLAGS-tst-sprintf.c = -Wno-format +tst-sprintf-ENV = LOCPATH=$(common-objpfx)localedata tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata diff --git a/libc/stdio-common/tst-sprintf.c b/libc/stdio-common/tst-sprintf.c index bfa79c9cc..42159a26f 100644 --- a/libc/stdio-common/tst-sprintf.c +++ b/libc/stdio-common/tst-sprintf.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <stdlib.h> +#include <locale.h> #include <string.h> #include <gnu/option-groups.h> @@ -61,5 +62,17 @@ main (void) result = 1; } + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + puts ("cannot set locale"); + result = 1; + } + else if (sprintf (buf, "%.8s\n", "Foo: \277") != 7 + || strcmp (buf, "Foo: \277\n") != 0) + { + printf ("sprintf (buf, \"%%.8s\\n\", \"Foo: \\277\") produced '%s' output\n", buf); + result = 1; + } + return result; } diff --git a/libc/stdio-common/vfprintf.c b/libc/stdio-common/vfprintf.c index a76b03acf..0a48ce2b5 100644 --- a/libc/stdio-common/vfprintf.c +++ b/libc/stdio-common/vfprintf.c @@ -1185,43 +1185,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) else if (!is_long && spec != L_('S')) \ { \ if (prec != -1) \ - { \ - /* Search for the end of the string, but don't search past \ - the length (in bytes) specified by the precision. Also \ - don't use incomplete characters. */ \ - if (! LOCALE_SUPPORT \ - ||_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1) \ - len = __strnlen (string, prec); \ - else \ - { \ - /* In case we have a multibyte character set the \ - situation is more complicated. We must not copy \ - bytes at the end which form an incomplete character. */\ - size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\ - wchar_t ignore[ignore_size]; \ - const char *str2 = string; \ - const char *strend = string + prec; \ - if (strend < string) \ - strend = (const char *) UINTPTR_MAX; \ - \ - mbstate_t ps; \ - memset (&ps, '\0', sizeof (ps)); \ - \ - while (str2 != NULL && str2 < strend) \ - if (__mbsnrtowcs (ignore, &str2, strend - str2, \ - ignore_size, &ps) == (size_t) -1) \ - { \ - /* Conversion function has set errno. */ \ - done = -1; \ - goto all_done; \ - } \ - \ - if (str2 == NULL) \ - len = strlen (string); \ - else \ - len = str2 - string - (ps.__count & 7); \ - } \ - } \ + /* Search for the end of the string, but don't search past \ + the length (in bytes) specified by the precision. */ \ + len = __strnlen (string, prec); \ else \ len = strlen (string); \ } \ diff --git a/libc/string/Makefile b/libc/string/Makefile index 096147dcc..de3ce2734 100644 --- a/libc/string/Makefile +++ b/libc/string/Makefile @@ -59,8 +59,7 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \ bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \ tst-strtok tst-strfry \ bug-strtok1 $(addprefix test-,$(strop-tests)) \ - tst-strxfrm2 tst-endian tst-svc2 bug-strstr1 \ - bug-strcasestr1 bug-strchr1 tst-strtok_r + tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1 tests-$(OPTION_EGLIBC_LOCALE_CODE) \ += tst-strxfrm bug-strcoll1 diff --git a/libc/string/bug-strchr1.c b/libc/string/bug-strchr1.c deleted file mode 100644 index 21155d8a7..000000000 --- a/libc/string/bug-strchr1.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdio.h> -#include <string.h> - -static int -do_test (void) -{ - char s[] __attribute__((aligned(16))) = "\xff"; - char *p = strchr (s, '\xfe'); - printf ("%p\n", p); - return p != NULL; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/libc/string/bug-strstr1.c b/libc/string/bug-strstr1.c deleted file mode 100644 index 889de1295..000000000 --- a/libc/string/bug-strstr1.c +++ /dev/null @@ -1,26 +0,0 @@ -#include <stdio.h> -#include <string.h> - -int main (int argc, char** argv) -{ - const char haystack[] = - "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD"; - - const char needle[] = - "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"; - - const char* sub = strstr (haystack, needle); - - if (sub != NULL) - { - int j; - - fprintf (stderr, "BUG: expected NULL, got:\n%s\n%s\n", sub, needle); - for (j = 0; needle[j] != '\0'; ++j) - putchar (needle[j] == sub[j] ? ' ' : '^'); - puts (""); - return 1; - } - - return 0; -} diff --git a/libc/string/str-two-way.h b/libc/string/str-two-way.h index 59609b868..d2572da40 100644 --- a/libc/string/str-two-way.h +++ b/libc/string/str-two-way.h @@ -75,18 +75,17 @@ # define CMP_FUNC memcmp #endif -#ifndef AVAILABLE1 -# define AVAILABLE1(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l) -#endif -#ifndef AVAILABLE2 -# define AVAILABLE2(h, h_l, j, n_l) (1) +/* Check for end-of-line in strstr and strcasestr routines. + We piggy-back matching procedure for detecting EOL where possible, + and use AVAILABLE macro otherwise. */ +#ifndef CHECK_EOL +# define CHECK_EOL (0) #endif + +/* Return NULL if argument is '\0'. */ #ifndef RET0_IF_0 # define RET0_IF_0(a) /* nothing */ #endif -#ifndef AVAILABLE1_USES_J -# define AVAILABLE1_USES_J (1) -#endif /* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN. Return the index of the first byte in the right half, and set @@ -283,11 +282,23 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, and use an optimized first-character loop. */ unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]); +#if CHECK_EOL + /* We start matching from the SUFFIX'th element, so make sure we + don't hit '\0' before that. */ + if (haystack_len < suffix + 1 + && !AVAILABLE (haystack, haystack_len, 0, suffix + 1)) + return NULL; +#endif + /* The two halves of needle are distinct; no extra memory is required, and any mismatch results in a maximal shift. */ period = MAX (suffix, needle_len - suffix) + 1; j = 0; - while (AVAILABLE1 (haystack, haystack_len, j, needle_len)) + while (1 +#if !CHECK_EOL + && AVAILABLE (haystack, haystack_len, j, needle_len) +#endif + ) { unsigned char haystack_char; const unsigned char *pneedle; @@ -298,13 +309,13 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, != (haystack_char = CANON_ELEMENT (*phaystack++))) { RET0_IF_0 (haystack_char); -#if AVAILABLE1_USES_J +#if CHECK_EOL ++j; #endif continue; } -#if !AVAILABLE1_USES_J +#if !CHECK_EOL /* Calculate J if it wasn't kept up-to-date in the first-character loop. */ j = phaystack - &haystack[suffix] - 1; @@ -346,8 +357,10 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, else j += i - suffix + 1; - if (!AVAILABLE2 (haystack, haystack_len, j, needle_len)) +#if CHECK_EOL + if (!AVAILABLE (haystack, haystack_len, j, needle_len)) break; +#endif phaystack = &haystack[suffix + j]; } diff --git a/libc/string/strcasestr.c b/libc/string/strcasestr.c index 9467b7a75..6aaf45f3a 100644 --- a/libc/string/strcasestr.c +++ b/libc/string/strcasestr.c @@ -43,10 +43,8 @@ #define AVAILABLE(h, h_l, j, n_l) \ (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ && ((h_l) = (j) + (n_l))) -#define AVAILABLE1(h, h_l, j, n_l) (true) -#define AVAILABLE2(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l) +#define CHECK_EOL (1) #define RET0_IF_0(a) if (!a) goto ret0 -#define AVAILABLE1_USES_J (0) #define CANON_ELEMENT(c) TOLOWER (c) #define CMP_FUNC(p1, p2, l) \ __strncasecmp ((const char *) (p1), (const char *) (p2), l) diff --git a/libc/string/strstr.c b/libc/string/strstr.c index cfed77119..d74cb4697 100644 --- a/libc/string/strstr.c +++ b/libc/string/strstr.c @@ -35,10 +35,8 @@ #define AVAILABLE(h, h_l, j, n_l) \ (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ && ((h_l) = (j) + (n_l))) -#define AVAILABLE1(h, h_l, j, n_l) (true) -#define AVAILABLE2(h, h_l, j, n_l) AVAILABLE (h, h_l, j, n_l) +#define CHECK_EOL (1) #define RET0_IF_0(a) if (!a) goto ret0 -#define AVAILABLE1_USES_J (0) #include "str-two-way.h" #undef strstr diff --git a/libc/string/test-strcasestr.c b/libc/string/test-strcasestr.c index 6c1a87861..fc0185863 100644 --- a/libc/string/test-strcasestr.c +++ b/libc/string/test-strcasestr.c @@ -57,8 +57,9 @@ IMPL (simple_strcasestr, 0) IMPL (strcasestr, 1) -static void -do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) +static int +check_result (impl_t *impl, const char *s1, const char *s2, + char *exp_result) { char *result = CALL (impl, s1, s2); if (result != exp_result) @@ -66,8 +67,16 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) error (0, 0, "Wrong result in function %s %s %s", impl->name, result, exp_result); ret = 1; - return; + return -1; } + return 0; +} + +static void +do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) +{ + if (check_result (impl, s1, s2, exp_result) < 0) + return; if (HP_TIMING_AVAIL) { @@ -136,12 +145,25 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2, putchar ('\n'); } +static void +check1 (void) +{ + const char s1[] = "AOKB"; + const char s2[] = "OK"; + char *exp_result; + + exp_result = stupid_strcasestr (s1, s2); + FOR_EACH_IMPL (impl, 0) + check_result (impl, s1, s2, exp_result); +} static int test_main (void) { test_init (); + check1 (); + printf ("%23s", ""); FOR_EACH_IMPL (impl, 0) printf ("\t%s", impl->name); diff --git a/libc/string/test-strchr.c b/libc/string/test-strchr.c index e544aa715..161ac458c 100644 --- a/libc/string/test-strchr.c +++ b/libc/string/test-strchr.c @@ -79,8 +79,8 @@ IMPL (stupid_STRCHR, 0) IMPL (simple_STRCHR, 0) IMPL (STRCHR, 1) -static void -do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) +static int +check_result (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) { CHAR *res = CALL (impl, s, c); if (res != exp_res) @@ -88,8 +88,16 @@ do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) error (0, 0, "Wrong result in function %s %#x %p %p", impl->name, c, res, exp_res); ret = 1; - return; + return -1; } + return 0; +} + +static void +do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) +{ + if (check_result (impl, s, c, exp_res) < 0) + return; if (HP_TIMING_AVAIL) { @@ -224,6 +232,17 @@ do_random_tests (void) } } +static void +check1 (void) +{ + char s[] __attribute__((aligned(16))) = "\xff"; + char c = '\xfe'; + char *exp_result = stupid_STRCHR (s, c); + + FOR_EACH_IMPL (impl, 0) + check_result (impl, s, c, exp_result); +} + int test_main (void) { @@ -231,6 +250,8 @@ test_main (void) test_init (); + check1 (); + printf ("%20s", ""); FOR_EACH_IMPL (impl, 0) printf ("\t%s", impl->name); diff --git a/libc/string/test-strstr.c b/libc/string/test-strstr.c index 6be460168..d4c0efc5b 100644 --- a/libc/string/test-strstr.c +++ b/libc/string/test-strstr.c @@ -55,8 +55,9 @@ IMPL (simple_strstr, 0) IMPL (strstr, 1) -static void -do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) +static int +check_result (impl_t *impl, const char *s1, const char *s2, + char *exp_result) { char *result = CALL (impl, s1, s2); if (result != exp_result) @@ -64,9 +65,18 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) error (0, 0, "Wrong result in function %s %s %s", impl->name, result, exp_result); ret = 1; - return; + return -1; } + return 0; +} + +static void +do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) +{ + if (check_result (impl, s1, s2, exp_result) < 0) + return; + if (HP_TIMING_AVAIL) { hp_timing_t start __attribute ((unused)); @@ -133,12 +143,43 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2, putchar ('\n'); } +static void +check1 (void) +{ + const char s1[] = + "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD"; + const char s2[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"; + char *exp_result; + + exp_result = stupid_strstr (s1, s2); + FOR_EACH_IMPL (impl, 0) + check_result (impl, s1, s2, exp_result); +} + +static void +check2 (void) +{ + const char s1[] = ", enable_static, \0, enable_shared, "; + char *exp_result; + char *s2 = (void *) buf1 + page_size - 18; + + strcpy (s2, s1); + exp_result = stupid_strstr (s1, s1 + 18); + FOR_EACH_IMPL (impl, 0) + { + check_result (impl, s1, s1 + 18, exp_result); + check_result (impl, s2, s1 + 18, exp_result); + } +} static int test_main (void) { test_init (); + check1 (); + check2 (); + printf ("%23s", ""); FOR_EACH_IMPL (impl, 0) printf ("\t%s", impl->name); diff --git a/libc/sysdeps/generic/_G_config.h b/libc/sysdeps/generic/_G_config.h index fc83565b9..e4f276731 100644 --- a/libc/sysdeps/generic/_G_config.h +++ b/libc/sysdeps/generic/_G_config.h @@ -28,8 +28,6 @@ typedef struct __off64_t __pos; __mbstate_t __state; } _G_fpos64_t; -#define _G_off64_t __off_t -#define _G_stat64 stat #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T # include <gconv.h> typedef union @@ -51,6 +49,11 @@ typedef union #define _G_IO_IO_FILE_VERSION 0x20001 +#define _G_OPEN64 __open64 +#define _G_LSEEK64 __lseek64 +#define _G_MMAP64 __mmap64 +#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf) + /* This is defined by <bits/stat.h> if `st_blksize' exists. */ #define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE) diff --git a/libc/sysdeps/generic/ldsodefs.h b/libc/sysdeps/generic/ldsodefs.h index 8d73212bb..9813d9bc2 100644 --- a/libc/sysdeps/generic/ldsodefs.h +++ b/libc/sysdeps/generic/ldsodefs.h @@ -41,6 +41,12 @@ __BEGIN_DECLS +#define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) +#define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ + + DT_EXTRANUM + DT_VALTAGIDX (tag)) +#define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ + + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag)) + /* We use this macro to refer to ELF types independent of the native wordsize. `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) diff --git a/libc/sysdeps/generic/math_private.h b/libc/sysdeps/generic/math_private.h index 5267ec327..b375bc0c5 100644 --- a/libc/sysdeps/generic/math_private.h +++ b/libc/sysdeps/generic/math_private.h @@ -364,6 +364,13 @@ extern double __slowexp (double __x); extern double __slowpow (double __x, double __y, double __z); extern void __docos (double __x, double __dx, double __v[]); +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ +extern float __x2y2m1f (float x, float y); +extern double __x2y2m1 (double x, double y); +extern long double __x2y2m1l (long double x, long double y); + #ifndef math_opt_barrier # define math_opt_barrier(x) \ ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; }) diff --git a/libc/sysdeps/i386/configure b/libc/sysdeps/i386/configure index 608ff29bc..7b3683f60 100755 --- a/libc/sysdeps/i386/configure +++ b/libc/sysdeps/i386/configure @@ -1,124 +1,4 @@ -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in @@ -162,6 +42,7 @@ else fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSE4 support" >&5 $as_echo_n "checking for SSE4 support... " >&6; } if ${libc_cv_cc_sse4+:} false; then : @@ -299,3 +180,4 @@ fi $as_echo "$libc_cv_cc_novzeroupper" >&6; } $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + diff --git a/libc/sysdeps/i386/fpu/libm-test-ulps b/libc/sysdeps/i386/fpu/libm-test-ulps index d35635ce0..239da44a7 100644 --- a/libc/sysdeps/i386/fpu/libm-test-ulps +++ b/libc/sysdeps/i386/fpu/libm-test-ulps @@ -880,6 +880,12 @@ float: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "Real part of: clog (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -5.421010862427522170184200798202494495630e-20 + 3.548665303440282824232502561095699343814e-4516 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i": +float: 1 +ifloat: 1 Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i": ildouble: 1 ldouble: 1 @@ -904,6 +910,9 @@ ldouble: 1 Test "Real part of: clog (0x1.fp+16383 - 0x1p-16445 i) == 11356.49165759582936919077408168801636572 - 0 i": ildouble: 1 ldouble: 1 +Test "Imaginary part of: clog (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 5.0844550531823026520677817684239496041087e-32 + 1.2627468605458094918919206628466016525397 i": +ildouble: 1 +ldouble: 1 Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i": ildouble: 1 ldouble: 1 @@ -922,6 +931,9 @@ ldouble: 1 Test "Real part of: clog (0x1p-16445 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 4.4469229730850767799109418892826021157328e-20 + 1.2046235979300843056806465045930070146351 i": +ildouble: 1 +ldouble: 1 Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i": float: 1 ifloat: 1 @@ -1068,6 +1080,17 @@ idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -2.354315103889861110220423157644627849164e-20 + 1.541165759405643564697852372112893034397e-4516 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: clog10 (0x1.000566p0 + 0x1.234p-10 i) == 3.604093470239754109961125085078190708674e-5 + 4.824745078422174667425851670822596859720e-4 i": ildouble: 1 ldouble: 1 @@ -1119,6 +1142,29 @@ ldouble: 1 Test "Real part of: clog10 (0x1.fp+16383 - 0x1p-16445 i) == 4932.061660674182269085496060792589701158 - 0 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x11682p-23 + 0x7ffed1p-23 i) == 5.0916490233953865181284669870035717560498e-13 + 0.6784968969384861816694467029319146542069 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i": +double: 1 +idouble: 1 Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i": double: 1 idouble: 1 @@ -1199,6 +1245,73 @@ ifloat: 1 Test "Real part of: clog10 (0x1p-8190 + 1.0 i) == 2.920285685286322365786846845062520925172e-4932 + 6.821881769209206737428918127156778851051e-1 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x659b70ab7971bp-53 + 0x1f5d111e08abecp-53 i) == -1.0893543813872082317104059174982092534059e-30 + 0.5954257879188711495921161433751775633232 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x81b7efa81fc35ad1p-65 + 0x1ef4b835f1c79d812p-65 i) == -4.3074341162203896332989394770760901408798e-39 + 0.5709443672155660428417571212549720987784 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -4.2289432987513243393180377141513840878196e-30 + 0.4252020027092323591068799049905597805296 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i": +double: 1 +idouble: 1 Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i": double: 1 idouble: 1 @@ -1490,9 +1603,9 @@ float: 1 ifloat: 1 Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": double: 2 -float: 3 +float: 4 idouble: 2 -ifloat: 3 +ifloat: 4 ildouble: 3 ldouble: 3 Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": @@ -1704,6 +1817,8 @@ ldouble: 1 # ctan Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": +float: 1 +ifloat: 1 double: 1 idouble: 1 ildouble: 1 @@ -1797,6 +1912,8 @@ Test "Imaginary part of: ctan_towardzero (0x1.921fb54442d18p+0 + 0x1p-1074 i) == ildouble: 1 ldouble: 1 Test "Real part of: ctan_towardzero (0x1.921fb6p+0 + 0x1p-149 i) == -2.287733242885645987394874673945769518150e7 + 7.334008549954377778731880988481078535821e-31 i": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "Imaginary part of: ctan_towardzero (0x1.921fb6p+0 + 0x1p-149 i) == -2.287733242885645987394874673945769518150e7 + 7.334008549954377778731880988481078535821e-31 i": @@ -1827,9 +1944,9 @@ ildouble: 2 ldouble: 2 Test "Imaginary part of: ctan_upward (0x1.921fb6p+0 + 0x1p-149 i) == -2.287733242885645987394874673945769518150e7 + 7.334008549954377778731880988481078535821e-31 i": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 1 ldouble: 1 @@ -1940,6 +2057,8 @@ ifloat: 3 ildouble: 4 ldouble: 4 Test "Imaginary part of: ctanh_towardzero (0x1p-149 + 0x1.921fb6p+0 i) == 7.334008549954377778731880988481078535821e-31 - 2.287733242885645987394874673945769518150e7 i": +float: 1 +ifloat: 1 ildouble: 1 ldouble: 1 @@ -1954,9 +2073,9 @@ ildouble: 1 ldouble: 1 Test "Real part of: ctanh_upward (0x1p-149 + 0x1.921fb6p+0 i) == 7.334008549954377778731880988481078535821e-31 - 2.287733242885645987394874673945769518150e7 i": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 1 ldouble: 1 Test "Imaginary part of: ctanh_upward (0x1p-149 + 0x1.921fb6p+0 i) == 7.334008549954377778731880988481078535821e-31 - 2.287733242885645987394874673945769518150e7 i": @@ -2564,9 +2683,6 @@ Test "sincos (0x1.fffff8p+127, &sin_res, &cos_res) puts 4.8578606313048733970111 float: 1 Test "sincos (0x1p+127, &sin_res, &cos_res) puts 6.23385512955870240370428801097126489001833e-01 in sin_res": float: 1 -Test "sincos (0x1p+50, &sin_res, &cos_res) puts 8.68095904660550604334592502063501320395739e-01 in cos_res": -float: 1 -ifloat: 1 Test "sincos (0x1p65, &sin_res, &cos_res) puts -0.047183876212354673805106149805700013943218 in sin_res": float: 1 ifloat: 1 @@ -3268,6 +3384,10 @@ ifloat: 1 ildouble: 1 ldouble: 1 +Function: Imaginary part of "clog": +ildouble: 1 +ldouble: 1 + Function: Real part of "clog10": double: 1 float: 1 @@ -3442,6 +3562,8 @@ ildouble: 1 ldouble: 1 Function: Real part of "ctan_towardzero": +float: 1 +ifloat: 1 double: 1 idouble: 1 ildouble: 1 @@ -3461,9 +3583,9 @@ ldouble: 2 Function: Imaginary part of "ctan_upward": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 4 ldouble: 4 @@ -3514,6 +3636,8 @@ ildouble: 4 ldouble: 4 Function: Imaginary part of "ctanh_towardzero": +float: 1 +ifloat: 1 double: 1 idouble: 1 ildouble: 1 @@ -3521,9 +3645,9 @@ ldouble: 1 Function: Real part of "ctanh_upward": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 4 ldouble: 4 diff --git a/libc/sysdeps/i386/i686/fpu/multiarch/Makefile b/libc/sysdeps/i386/i686/fpu/multiarch/Makefile index aa28f7284..7d9089232 100644 --- a/libc/sysdeps/i386/i686/fpu/multiarch/Makefile +++ b/libc/sysdeps/i386/i686/fpu/multiarch/Makefile @@ -1,3 +1,4 @@ ifeq ($(subdir),math) -libm-sysdep_routines += e_expf-sse2 e_expf-ia32 s_sinf-sse2 s_cosf-sse2 +libm-sysdep_routines += e_expf-sse2 e_expf-ia32 s_sinf-sse2 s_cosf-sse2 \ + s_sincosf-sse2 endif diff --git a/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S new file mode 100644 index 000000000..622f07ac8 --- /dev/null +++ b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S @@ -0,0 +1,586 @@ +/* Optimized with sse2 version of sincosf + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#define __need_Emath +#include <bits/errno.h> + +/* Short algorithm description: + * + * 1) if |x|==0: sin(x)=x, + * cos(x)=1. + * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed, + * cos(x)=1-|x|. + * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1, + * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1 + * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))), + * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). + * 5) if |x| < 9*Pi/4: + * 5.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4. + * 5.2) Reconstruction: + * sign_sin = sign(x) * (-1.0)^(( n >>2)&1) + * sign_cos = (-1.0)^(((n+2)>>2)&1) + * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t + * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s + * if(n&2 != 0) { + * using cos(t) and sin(t) polynomials for |t|<Pi/4, results are + * cos(x) = poly_sin * sign_cos + * sin(x) = poly_cos * sign_sin + * } else { + * sin(x) = poly_sin * sign_sin + * cos(x) = poly_cos * sign_cos + * } + * 6) if |x| < 2^23, large args: + * 6.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4 + * 6.2) Reconstruction same as (5.2). + * 7) if |x| >= 2^23, very large args: + * 7.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4. + * 7.2) Reconstruction same as (5.2). + * 8) if x is Inf, return x-x, and set errno=EDOM. + * 9) if x is NaN, return x-x. + * + * Special cases: + * sin/cos(+-0) = +-0/1 not raising inexact/underflow, + * sin/cos(subnormal) raises inexact/underflow, + * sin/cos(min_normalized) raises inexact/underflow, + * sin/cos(normalized) raises inexact, + * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM, + * sin/cos(NaN) = NaN. + */ + +#ifdef PIC +# define MO1(symbol) L(symbol)##@GOTOFF(%ebx) +# define MO2(symbol,reg2,_scale) L(symbol)##@GOTOFF(%ebx,reg2,_scale) +# define CFI_PUSH(REG) cfi_adjust_cfa_offset(4); cfi_rel_offset(REG,0) +# define CFI_POP(REG) cfi_adjust_cfa_offset(-4); cfi_restore(REG) +# define PUSH(REG) pushl REG; CFI_PUSH(REG) +# define POP(REG) popl REG; CFI_POP(REG) +# define ENTRANCE PUSH(%ebx); LOAD_PIC_REG(bx) +# define RETURN POP(%ebx); ret; CFI_PUSH(%ebx) +# define ARG_X 8(%esp) +# define ARG_SIN_PTR 12(%esp) +# define ARG_COS_PTR 16(%esp) +#else +# define MO1(symbol) L(symbol) +# define MO2(symbol,reg2,_scale) L(symbol)(,reg2,_scale) +# define ENTRANCE +# define RETURN ret +# define ARG_X 4(%esp) +# define ARG_SIN_PTR 8(%esp) +# define ARG_COS_PTR 12(%esp) +#endif + + .text +ENTRY(__sincosf_sse2) + /* Input: single precision x on stack at address ARG_X */ + /* pointer to sin result on stack at address ARG_SIN_PTR */ + /* pointer to cos result on stack at address ARG_COS_PTR */ + + ENTRANCE + movl ARG_X, %eax /* Bits of x */ + cvtss2sd ARG_X, %xmm0 /* DP x */ + andl $0x7fffffff, %eax /* |x| */ + + cmpl $0x3f490fdb, %eax /* |x|<Pi/4 ? */ + jb L(arg_less_pio4) + + /* Here if |x|>=Pi/4 */ + movd %eax, %xmm3 /* SP |x| */ + andpd MO1(DP_ABS_MASK),%xmm0 /* DP |x| */ + movss MO1(SP_INVPIO4), %xmm2 /* SP 1/(Pi/4) */ + + cmpl $0x40e231d6, %eax /* |x|<9*Pi/4 ? */ + jae L(large_args) + + /* Here if Pi/4<=|x|<9*Pi/4 */ + mulss %xmm3, %xmm2 /* SP |x|/(Pi/4) */ + movl ARG_X, %ecx /* Load x */ + cvttss2si %xmm2, %eax /* k, number of Pi/4 in x */ + shrl $29, %ecx /* (sign of x) << 2 */ + addl $1, %eax /* k+1 */ + movl $0x0e, %edx + andl %eax, %edx /* j = (k+1)&0x0e */ + subsd MO2(PIO4J,%edx,8), %xmm0/* t = |x| - j * Pi/4 */ + +L(reconstruction): + /* Input: %eax=n, %xmm0=t, %ecx=sign(x) */ + + movaps %xmm0, %xmm4 /* t */ + movhpd MO1(DP_ONES), %xmm4 /* 1|t */ + mulsd %xmm0, %xmm0 /* y=t^2 */ + movl $2, %edx + unpcklpd %xmm0, %xmm0 /* y|y */ + addl %eax, %edx /* k+2 */ + movaps %xmm0, %xmm1 /* y|y */ + mulpd %xmm0, %xmm0 /* z=t^4|z=t^4 */ + + movaps MO1(DP_SC4), %xmm2 /* S4 */ + mulpd %xmm0, %xmm2 /* z*S4 */ + movaps MO1(DP_SC3), %xmm3 /* S3 */ + mulpd %xmm0, %xmm3 /* z*S3 */ + xorl %eax, %ecx /* (sign_x ^ (k>>2))<<2 */ + addpd MO1(DP_SC2), %xmm2 /* S2+z*S4 */ + mulpd %xmm0, %xmm2 /* z*(S2+z*S4) */ + shrl $2, %edx /* (k+2)>>2 */ + addpd MO1(DP_SC1), %xmm3 /* S1+z*S3 */ + mulpd %xmm0, %xmm3 /* z*(S1+z*S3) */ + shrl $2, %ecx /* sign_x ^ k>>2 */ + addpd MO1(DP_SC0), %xmm2 /* S0+z*(S2+z*S4) */ + andl $1, %edx /* sign_cos = ((k+2)>>2)&1 */ + mulpd %xmm1, %xmm2 /* y*(S0+z*(S2+z*S4)) */ + andl $1, %ecx /* sign_sin = sign_x ^ ((k>>2)&1) */ + addpd %xmm2, %xmm3 /* y*(S0+y*(S1+y*(S2+y*(S3+y*S4)))) */ + mulpd %xmm4, %xmm3 /*t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/ + testl $2, %eax /* n&2 != 0 ? */ + addpd %xmm4, %xmm3 /*t+t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/ + jnz L(sin_result_sin_poly) + +/*L(sin_result_cos_poly):*/ + /* + * Here if + * cos(x) = poly_sin * sign_cos + * sin(x) = poly_cos * sign_sin + */ + movsd MO2(DP_ONES,%ecx,8), %xmm4/* 0|sign_sin */ + movhpd MO2(DP_ONES,%edx,8), %xmm4/* sign_cos|sign_sin */ + mulpd %xmm4, %xmm3 /* result_cos|result_sin */ + movl ARG_SIN_PTR, %eax + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movl ARG_COS_PTR, %ecx + movss %xmm0, (%eax) /* store sin(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */ + movss %xmm0, (%ecx) /* store cos(x) */ + RETURN + + .p2align 4 +L(sin_result_sin_poly): + /* + * Here if + * sin(x) = poly_sin * sign_sin + * cos(x) = poly_cos * sign_cos + */ + movsd MO2(DP_ONES,%edx,8), %xmm4/* 0|sign_cos */ + movhpd MO2(DP_ONES,%ecx,8), %xmm4/* sign_sin|sign_cos */ + mulpd %xmm4, %xmm3 /* result_sin|result_cos */ + movl ARG_SIN_PTR, %eax + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movl ARG_COS_PTR, %ecx + movss %xmm0, (%ecx) /* store cos(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move sin(x) to xmm0[0] */ + movss %xmm0, (%eax) /* store sin(x) */ + RETURN + + .p2align 4 +L(large_args): + /* Here if |x|>=9*Pi/4 */ + cmpl $0x7f800000, %eax /* x is Inf or NaN ? */ + jae L(arg_inf_or_nan) + + /* Here if finite |x|>=9*Pi/4 */ + cmpl $0x4b000000, %eax /* |x|<2^23 ? */ + jae L(very_large_args) + + /* Here if 9*Pi/4<=|x|<2^23 */ + movsd MO1(DP_INVPIO4), %xmm1 /* 1/(Pi/4) */ + mulsd %xmm0, %xmm1 /* |x|/(Pi/4) */ + cvttsd2si %xmm1, %eax /* k=trunc(|x|/(Pi/4)) */ + addl $1, %eax /* k+1 */ + movl %eax, %edx + andl $0xfffffffe, %edx /* j=(k+1)&0xfffffffe */ + cvtsi2sdl %edx, %xmm4 /* DP j */ + movl ARG_X, %ecx /* Load x */ + movsd MO1(DP_PIO4HI), %xmm2 /* -PIO4HI = high part of -Pi/4 */ + shrl $29, %ecx /* (sign of x) << 2 */ + mulsd %xmm4, %xmm2 /* -j*PIO4HI */ + movsd MO1(DP_PIO4LO), %xmm3 /* -PIO4LO = low part of -Pi/4 */ + addsd %xmm2, %xmm0 /* |x| - j*PIO4HI */ + mulsd %xmm3, %xmm4 /* j*PIO4LO */ + addsd %xmm4, %xmm0 /* t = |x| - j*PIO4HI - j*PIO4LO */ + jmp L(reconstruction) + + .p2align 4 +L(very_large_args): + /* Here if finite |x|>=2^23 */ + + /* bitpos = (ix>>23) - BIAS_32 + 59; */ + shrl $23, %eax /* eb = biased exponent of x */ + subl $68, %eax /* bitpos=eb-0x7f+59, where 0x7f */ + /*is exponent bias */ + movl $28, %ecx /* %cl=28 */ + movl %eax, %edx /* bitpos copy */ + + /* j = bitpos/28; */ + div %cl /* j in register %al=%ax/%cl */ + movapd %xmm0, %xmm3 /* |x| */ + andl $0xff, %eax /* clear unneeded remainder from %ah*/ + + imull $28, %eax, %ecx /* j*28 */ + movsd MO1(DP_HI_MASK), %xmm4 /* DP_HI_MASK */ + movapd %xmm0, %xmm5 /* |x| */ + mulsd -2*8+MO2(_FPI,%eax,8), %xmm3/* tmp3 = FPI[j-2]*|x| */ + movapd %xmm0, %xmm1 /* |x| */ + mulsd -1*8+MO2(_FPI,%eax,8), %xmm5/* tmp2 = FPI[j-1]*|x| */ + mulsd 0*8+MO2(_FPI,%eax,8), %xmm0/* tmp0 = FPI[j]*|x| */ + addl $19, %ecx /* j*28+19 */ + mulsd 1*8+MO2(_FPI,%eax,8), %xmm1/* tmp1 = FPI[j+1]*|x| */ + cmpl %ecx, %edx /* bitpos>=j*28+19 ? */ + jl L(very_large_skip1) + + /* Here if bitpos>=j*28+19 */ + andpd %xmm3, %xmm4 /* HI(tmp3) */ + subsd %xmm4, %xmm3 /* tmp3 = tmp3 - HI(tmp3) */ +L(very_large_skip1): + + movsd MO1(DP_2POW52), %xmm6 + movapd %xmm5, %xmm2 /* tmp2 copy */ + addsd %xmm3, %xmm5 /* tmp5 = tmp3 + tmp2 */ + movl $1, %edx + addsd %xmm5, %xmm6 /* tmp6 = tmp5 + 2^52 */ + movsd 8+MO1(DP_2POW52), %xmm4 + movd %xmm6, %eax /* k = I64_LO(tmp6); */ + addsd %xmm6, %xmm4 /* tmp4 = tmp6 - 2^52 */ + movl ARG_X, %ecx /* Load x */ + comisd %xmm5, %xmm4 /* tmp4 > tmp5 ? */ + jbe L(very_large_skip2) + + /* Here if tmp4 > tmp5 */ + subl $1, %eax /* k-- */ + addsd 8+MO1(DP_ONES), %xmm4 /* tmp4 -= 1.0 */ +L(very_large_skip2): + + andl %eax, %edx /* k&1 */ + subsd %xmm4, %xmm3 /* tmp3 -= tmp4 */ + addsd MO2(DP_ZERONE,%edx,8), %xmm3/* t = DP_ZERONE[k&1] + tmp3 */ + addsd %xmm2, %xmm3 /* t += tmp2 */ + shrl $29, %ecx /* (sign of x) << 2 */ + addsd %xmm3, %xmm0 /* t += tmp0 */ + addl $1, %eax /* n=k+1 */ + addsd %xmm1, %xmm0 /* t += tmp1 */ + mulsd MO1(DP_PIO4), %xmm0 /* t *= PI04 */ + + jmp L(reconstruction) /* end of very_large_args peth */ + + .p2align 4 +L(arg_less_pio4): + /* Here if |x|<Pi/4 */ + cmpl $0x3d000000, %eax /* |x|<2^-5 ? */ + jl L(arg_less_2pn5) + + /* Here if 2^-5<=|x|<Pi/4 */ + movaps %xmm0, %xmm3 /* DP x */ + movhpd MO1(DP_ONES), %xmm3 /* DP 1|x */ + mulsd %xmm0, %xmm0 /* DP y=x^2 */ + unpcklpd %xmm0, %xmm0 /* DP y|y */ + movaps %xmm0, %xmm1 /* y|y */ + mulpd %xmm0, %xmm0 /* z=x^4|z=x^4 */ + + movapd MO1(DP_SC4), %xmm4 /* S4 */ + mulpd %xmm0, %xmm4 /* z*S4 */ + movapd MO1(DP_SC3), %xmm5 /* S3 */ + mulpd %xmm0, %xmm5 /* z*S3 */ + addpd MO1(DP_SC2), %xmm4 /* S2+z*S4 */ + mulpd %xmm0, %xmm4 /* z*(S2+z*S4) */ + addpd MO1(DP_SC1), %xmm5 /* S1+z*S3 */ + mulpd %xmm0, %xmm5 /* z*(S1+z*S3) */ + addpd MO1(DP_SC0), %xmm4 /* S0+z*(S2+z*S4) */ + mulpd %xmm1, %xmm4 /* y*(S0+z*(S2+z*S4)) */ + mulpd %xmm3, %xmm5 /* x*z*(S1+z*S3) */ + mulpd %xmm3, %xmm4 /* x*y*(S0+z*(S2+z*S4)) */ + addpd %xmm5, %xmm4 /*x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/ + movl ARG_SIN_PTR, %eax + addpd %xmm4, %xmm3 /*x+x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/ + movl ARG_COS_PTR, %ecx + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movss %xmm0, (%eax) /* store sin(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */ + movss %xmm0, (%ecx) /* store cos(x) */ + RETURN + + .p2align 4 +L(arg_less_2pn5): + /* Here if |x|<2^-5 */ + cmpl $0x32000000, %eax /* |x|<2^-27 ? */ + jl L(arg_less_2pn27) + + /* Here if 2^-27<=|x|<2^-5 */ + movaps %xmm0, %xmm1 /* DP x */ + movhpd MO1(DP_ONES), %xmm1 /* DP 1|x */ + mulsd %xmm0, %xmm0 /* DP x^2 */ + unpcklpd %xmm0, %xmm0 /* DP x^2|x^2 */ + + movaps MO1(DP_SINCOS2_1), %xmm3/* DP DP_SIN2_1 */ + mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_1 */ + addpd MO1(DP_SINCOS2_0), %xmm3/* DP DP_SIN2_0+x^2*DP_SIN2_1 */ + mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_0+x^4*DP_SIN2_1 */ + mulpd %xmm1, %xmm3 /* DP x^3*DP_SIN2_0+x^5*DP_SIN2_1 */ + addpd %xmm1, %xmm3 /* DP x+x^3*DP_SIN2_0+x^5*DP_SIN2_1 */ + movl ARG_SIN_PTR, %eax + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movl ARG_COS_PTR, %ecx + movss %xmm0, (%eax) /* store sin(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */ + movss %xmm0, (%ecx) /* store cos(x) */ + RETURN + + .p2align 4 +L(arg_less_2pn27): + movss ARG_X, %xmm7 /* SP x */ + cmpl $0, %eax /* x=0 ? */ + je L(arg_zero) /* in case x=0 return sin(+-0)==+-0 */ + /* Here if |x|<2^-27 */ + /* + * Special cases here: + * sin(subnormal) raises inexact/underflow + * sin(min_normalized) raises inexact/underflow + * sin(normalized) raises inexact + * cos(here)=1-|x| (raising inexact) + */ + movaps %xmm0, %xmm3 /* DP x */ + mulsd MO1(DP_SMALL), %xmm0 /* DP x*DP_SMALL */ + subsd %xmm0, %xmm3 /* DP sin result is x-x*DP_SMALL */ + andps MO1(SP_ABS_MASK), %xmm7 /* SP |x| */ + cvtsd2ss %xmm3, %xmm0 /* sin(x) */ + movl ARG_SIN_PTR, %eax + movss MO1(SP_ONE), %xmm1 /* SP 1.0 */ + movss %xmm0, (%eax) /* sin(x) store */ + movl ARG_COS_PTR, %ecx + subss %xmm7, %xmm1 /* cos(x) */ + movss %xmm1, (%ecx) /* cos(x) store */ + RETURN + + .p2align 4 +L(arg_zero): + movss MO1(SP_ONE), %xmm0 /* 1.0 */ + movl ARG_SIN_PTR, %eax + movl ARG_COS_PTR, %ecx + movss %xmm7, (%eax) /* sin(+-0)==x */ + movss %xmm0, (%ecx) /* cos(+-0)==1 */ + RETURN + + .p2align 4 +L(arg_inf_or_nan): + movss ARG_X, %xmm7 /* SP x */ + /* Here if |x| is Inf or NAN */ + jne L(skip_errno_setting) /* in case of x is NaN */ + + /* Here if x is Inf. Set errno to EDOM. */ + call JUMPTARGET(__errno_location) + movl $EDOM, (%eax) + + .p2align 4 +L(skip_errno_setting): + /* Here if |x| is Inf or NAN. Continued. */ + subss %xmm7, %xmm7 /* x-x, result is NaN */ + movl ARG_SIN_PTR, %eax + movl ARG_COS_PTR, %ecx + movss %xmm7, (%eax) + movss %xmm7, (%ecx) + RETURN +END(__sincosf_sse2) + + .section .rodata, "a" + .p2align 3 +L(PIO4J): /* Table of j*Pi/4, for j=0,1,..,10 */ + .long 0x00000000,0x00000000 + .long 0x54442d18,0x3fe921fb + .long 0x54442d18,0x3ff921fb + .long 0x7f3321d2,0x4002d97c + .long 0x54442d18,0x400921fb + .long 0x2955385e,0x400f6a7a + .long 0x7f3321d2,0x4012d97c + .long 0xe9bba775,0x4015fdbb + .long 0x54442d18,0x401921fb + .long 0xbeccb2bb,0x401c463a + .long 0x2955385e,0x401f6a7a + .type L(PIO4J), @object + ASM_SIZE_DIRECTIVE(L(PIO4J)) + + .p2align 3 +L(_FPI): /* 4/Pi broken into sum of positive DP values */ + .long 0x00000000,0x00000000 + .long 0x6c000000,0x3ff45f30 + .long 0x2a000000,0x3e3c9c88 + .long 0xa8000000,0x3c54fe13 + .long 0xd0000000,0x3aaf47d4 + .long 0x6c000000,0x38fbb81b + .long 0xe0000000,0x3714acc9 + .long 0x7c000000,0x3560e410 + .long 0x56000000,0x33bca2c7 + .long 0xac000000,0x31fbd778 + .long 0xe0000000,0x300b7246 + .long 0xe8000000,0x2e5d2126 + .long 0x48000000,0x2c970032 + .long 0xe8000000,0x2ad77504 + .long 0xe0000000,0x290921cf + .long 0xb0000000,0x274deb1c + .long 0xe0000000,0x25829a73 + .long 0xbe000000,0x23fd1046 + .long 0x10000000,0x2224baed + .long 0x8e000000,0x20709d33 + .long 0x80000000,0x1e535a2f + .long 0x64000000,0x1cef904e + .long 0x30000000,0x1b0d6398 + .long 0x24000000,0x1964ce7d + .long 0x16000000,0x17b908bf + .type L(_FPI), @object + ASM_SIZE_DIRECTIVE(L(_FPI)) + +/* Coefficients of polynomials for */ +/* sin(x)~=x+x*x^2*(DP_SIN2_0+x^2*DP_SIN2_1) in low DP part, */ +/* cos(x)~=1+1*x^2*(DP_COS2_0+x^2*DP_COS2_1) in high DP part, */ +/* for |x|<2^-5. */ + .p2align 4 +L(DP_SINCOS2_0): + .long 0x5543d49d,0xbfc55555 + .long 0xff5cc6fd,0xbfdfffff + .type L(DP_SINCOS2_0), @object + ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_0)) + + .p2align 4 +L(DP_SINCOS2_1): + .long 0x75cec8c5,0x3f8110f4 + .long 0xb178dac5,0x3fa55514 + .type L(DP_SINCOS2_1), @object + ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_1)) + + .p2align 3 +L(DP_ZERONE): + .long 0x00000000,0x00000000 /* 0.0 */ + .long 0x00000000,0xbff00000 /* 1.0 */ + .type L(DP_ZERONE), @object + ASM_SIZE_DIRECTIVE(L(DP_ZERONE)) + + .p2align 3 +L(DP_ONES): + .long 0x00000000,0x3ff00000 /* +1.0 */ + .long 0x00000000,0xbff00000 /* -1.0 */ + .type L(DP_ONES), @object + ASM_SIZE_DIRECTIVE(L(DP_ONES)) + +/* Coefficients of polynomials for */ +/* sin(t)~=t+t*t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4)))) in low DP part, */ +/* cos(t)~=1+1*t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4)))) in high DP part, */ +/* for |t|<Pi/4. */ + .p2align 4 +L(DP_SC4): + .long 0x1674b58a,0xbe5a947e + .long 0xdd8844d7,0xbe923c97 + .type L(DP_SC4), @object + ASM_SIZE_DIRECTIVE(L(DP_SC4)) + + .p2align 4 +L(DP_SC3): + .long 0x64e6b5b4,0x3ec71d72 + .long 0x9ac43cc0,0x3efa00eb + .type L(DP_SC3), @object + ASM_SIZE_DIRECTIVE(L(DP_SC3)) + + .p2align 4 +L(DP_SC2): + .long 0x8b4bd1f9,0xbf2a019f + .long 0x348b6874,0xbf56c16b + .type L(DP_SC2), @object + ASM_SIZE_DIRECTIVE(L(DP_SC2)) + + .p2align 4 +L(DP_SC1): + .long 0x10c2688b,0x3f811111 + .long 0x545c50c7,0x3fa55555 + .type L(DP_SC1), @object + ASM_SIZE_DIRECTIVE(L(DP_SC1)) + + .p2align 4 +L(DP_SC0): + .long 0x55551cd9,0xbfc55555 + .long 0xfffe98ae,0xbfdfffff + .type L(DP_SC0), @object + ASM_SIZE_DIRECTIVE(L(DP_SC0)) + + .p2align 3 +L(DP_SMALL): + .long 0x00000000,0x3cd00000 /* 2^(-50) */ + .type L(DP_SMALL), @object + ASM_SIZE_DIRECTIVE(L(DP_SMALL)) + + .p2align 3 +L(DP_PIO4): + .long 0x54442d18,0x3fe921fb /* Pi/4 */ + .type L(DP_PIO4), @object + ASM_SIZE_DIRECTIVE(L(DP_PIO4)) + + .p2align 3 +L(DP_2POW52): + .long 0x00000000,0x43300000 /* +2^52 */ + .long 0x00000000,0xc3300000 /* -2^52 */ + .type L(DP_2POW52), @object + ASM_SIZE_DIRECTIVE(L(DP_2POW52)) + + .p2align 3 +L(DP_INVPIO4): + .long 0x6dc9c883,0x3ff45f30 /* 4/Pi */ + .type L(DP_INVPIO4), @object + ASM_SIZE_DIRECTIVE(L(DP_INVPIO4)) + + .p2align 3 +L(DP_PIO4HI): + .long 0x54000000,0xbfe921fb /* High part of Pi/4 */ + .type L(DP_PIO4HI), @object + ASM_SIZE_DIRECTIVE(L(DP_PIO4HI)) + + .p2align 3 +L(DP_PIO4LO): + .long 0x11A62633,0xbe010b46 /* Low part of Pi/4 */ + .type L(DP_PIO4LO), @object + ASM_SIZE_DIRECTIVE(L(DP_PIO4LO)) + + .p2align 2 +L(SP_INVPIO4): + .long 0x3fa2f983 /* 4/Pi */ + .type L(SP_INVPIO4), @object + ASM_SIZE_DIRECTIVE(L(SP_INVPIO4)) + + .p2align 4 +L(DP_ABS_MASK): /* Mask for getting DP absolute value */ + .long 0xffffffff,0x7fffffff + .long 0xffffffff,0x7fffffff + .type L(DP_ABS_MASK), @object + ASM_SIZE_DIRECTIVE(L(DP_ABS_MASK)) + + .p2align 3 +L(DP_HI_MASK): /* Mask for getting high 21 bits of DP value */ + .long 0x00000000,0xffffffff + .type L(DP_HI_MASK), @object + ASM_SIZE_DIRECTIVE(L(DP_HI_MASK)) + + .p2align 4 +L(SP_ABS_MASK): /* Mask for getting SP absolute value */ + .long 0x7fffffff,0x7fffffff + .long 0x7fffffff,0x7fffffff + .type L(SP_ABS_MASK), @object + ASM_SIZE_DIRECTIVE(L(SP_ABS_MASK)) + + .p2align 2 +L(SP_ONE): + .long 0x3f800000 /* 1.0 */ + .type L(SP_ONE), @object + ASM_SIZE_DIRECTIVE(L(SP_ONE)) + +weak_alias(__sincosf, sincosf) diff --git a/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c new file mode 100644 index 000000000..c5e856a21 --- /dev/null +++ b/libc/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c @@ -0,0 +1,29 @@ +/* Multiple versions of sincosf + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <init-arch.h> + +extern void __sincosf_sse2 (float, float *, float *); +extern void __sincosf_ia32 (float, float *, float *); +void __sincosf (float, float *, float *); + +libm_ifunc (__sincosf, HAS_SSE2 ? __sincosf_sse2 : __sincosf_ia32); +weak_alias (__sincosf, sincosf); + +#define SINCOSF __sincosf_ia32 +#include <sysdeps/ieee754/flt-32/s_sincosf.c> diff --git a/libc/sysdeps/i386/init-first.c b/libc/sysdeps/i386/init-first.c deleted file mode 100644 index edea7f269..000000000 --- a/libc/sysdeps/i386/init-first.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. For i386/Unix. - Copyright (C) 1995-2012 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, see - <http://www.gnu.org/licenses/>. */ - -#include <ctype.h> -#include <unistd.h> - -extern void __libc_init (int, char **, char **); -#ifdef USE_NONOPTION_FLAGS -extern void __getopt_clean_environment (char **); -#endif -extern void __libc_global_ctors (void); - -int __libc_multiple_libcs attribute_hidden = 1; - -static void -init (int *data) -{ - int argc = *data; - char **argv = (void *) (data + 1); - char **envp = &argv[argc + 1]; - - __environ = envp; - __libc_init (argc, argv, envp); - -#ifdef USE_NONOPTION_FLAGS - /* This is a hack to make the special getopt in GNU libc working. */ - __getopt_clean_environment (envp); -#endif - - /* Initialize ctype data. */ - __ctype_init (); -} - -#ifdef SHARED -/* This function is called to initialize the shared C library. - It is called just before the user _start code from i386/start.S, - with the stack set up as that code gets it. */ - -/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT - pointer in the dynamic section based solely on that. It is convention - for this function to be in the `.init' section, but the symbol name is - the only thing that really matters!! */ -/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ - -void -_init (int argc, ...) -{ - init (&argc); - -#ifndef NO_CTORS_DTORS_SECTIONS - __libc_global_ctors (); -#endif -} -#endif - - -void -__libc_init_first (int argc __attribute__ ((unused)), ...) -{ -#ifndef SHARED - init (&argc); -#endif -} diff --git a/libc/sysdeps/ieee754/dbl-64/s_fma.c b/libc/sysdeps/ieee754/dbl-64/s_fma.c index ce3bd36fa..5e21461a4 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_fma.c +++ b/libc/sysdeps/ieee754/dbl-64/s_fma.c @@ -49,6 +49,11 @@ __fma (double x, double y, double z) && u.ieee.exponent != 0x7ff && v.ieee.exponent != 0x7ff) return (z + x) + y; + /* If z is zero and x are y are nonzero, compute the result + as x * y to avoid the wrong sign of a zero result if x * y + underflows to 0. */ + if (z == 0 && x != 0 && y != 0) + return x * y; /* If x or y or z is Inf/NaN, or if fma will certainly overflow, or if x * y is less than half of DBL_DENORM_MIN, compute as x * y + z. */ @@ -128,6 +133,11 @@ __fma (double x, double y, double z) y = v.d; z = w.d; } + + /* Ensure correct sign of exact 0 + 0. */ + if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0)) + return x * y + z; + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ #define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1) double x1 = x * C; diff --git a/libc/sysdeps/ieee754/dbl-64/s_fmaf.c b/libc/sysdeps/ieee754/dbl-64/s_fmaf.c index e7a0650f0..a4f12d9f7 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_fmaf.c +++ b/libc/sysdeps/ieee754/dbl-64/s_fmaf.c @@ -32,8 +32,15 @@ float __fmaf (float x, float y, float z) { fenv_t env; + /* Multiplication is always exact. */ double temp = (double) x * (double) y; + + /* Ensure correct sign of an exact zero result by performing the + addition in the original rounding mode in that case. */ + if (temp == -z) + return (float) temp + z; + union ieee754_double u; libc_feholdexcept_setround (&env, FE_TOWARDZERO); diff --git a/libc/sysdeps/ieee754/dbl-64/x2y2m1.c b/libc/sysdeps/ieee754/dbl-64/x2y2m1.c new file mode 100644 index 000000000..4badde3be --- /dev/null +++ b/libc/sysdeps/ieee754/dbl-64/x2y2m1.c @@ -0,0 +1,111 @@ +/* Compute x^2 + y^2 - 1, without large cancellation error. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <float.h> +#include <stdlib.h> + +/* Calculate X + Y exactly and store the result in *HI + *LO. It is + given that |X| >= |Y| and the values are small enough that no + overflow occurs. */ + +static inline void +add_split (double *hi, double *lo, double x, double y) +{ + /* Apply Dekker's algorithm. */ + *hi = x + y; + *lo = (x - *hi) + y; +} + +/* Calculate X * Y exactly and store the result in *HI + *LO. It is + given that the values are small enough that no overflow occurs and + large enough (or zero) that no underflow occurs. */ + +static inline void +mul_split (double *hi, double *lo, double x, double y) +{ +#ifdef __FP_FAST_FMA + /* Fast built-in fused multiply-add. */ + *hi = x * y; + *lo = __builtin_fma (x, y, -*hi); +#elif defined FP_FAST_FMA + /* Fast library fused multiply-add, compiler before GCC 4.6. */ + *hi = x * y; + *lo = __fma (x, y, -*hi); +#else + /* Apply Dekker's algorithm. */ + *hi = x * y; +# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1) + double x1 = x * C; + double y1 = y * C; +# undef C + x1 = (x - x1) + x1; + y1 = (y - y1) + y1; + double x2 = x - x1; + double y2 = y - y1; + *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2; +#endif +} + +/* Compare absolute values of floating-point values pointed to by P + and Q for qsort. */ + +static int +compare (const void *p, const void *q) +{ + double pd = fabs (*(const double *) p); + double qd = fabs (*(const double *) q); + if (pd < qd) + return -1; + else if (pd == qd) + return 0; + else + return 1; +} + +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ + +double +__x2y2m1 (double x, double y) +{ + double vals[4]; + SET_RESTORE_ROUND (FE_TONEAREST); + mul_split (&vals[1], &vals[0], x, x); + mul_split (&vals[3], &vals[2], y, y); + if (x >= 0.75) + vals[1] -= 1.0; + else + { + vals[1] -= 0.5; + vals[3] -= 0.5; + } + qsort (vals, 4, sizeof (double), compare); + /* Add up the values so that each element of VALS has absolute value + at most equal to the last set bit of the next nonzero + element. */ + for (size_t i = 0; i <= 2; i++) + { + add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]); + qsort (vals + i + 1, 3 - i, sizeof (double), compare); + } + /* Now any error from this addition will be small. */ + return vals[3] + vals[2] + vals[1] + vals[0]; +} diff --git a/libc/string/bug-strcasestr1.c b/libc/sysdeps/ieee754/dbl-64/x2y2m1f.c index e8334d709..fcaa70851 100644 --- a/libc/string/bug-strcasestr1.c +++ b/libc/sysdeps/ieee754/dbl-64/x2y2m1f.c @@ -1,4 +1,4 @@ -/* Test for non-submitted strcasestr bug. +/* Compute x^2 + y^2 - 1, without large cancellation error. Copyright (C) 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -16,24 +16,17 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdio.h> -#include <string.h> +#include <math.h> +#include <math_private.h> +#include <float.h> -#define TEST_FUNCTION do_test () -static int -do_test (void) -{ - const char haystack[] = "AOKB"; - const char needle[] = "OK"; - const char *sub = strcasestr (haystack, needle); - - if (sub == NULL) - { - fprintf (stderr, "BUG: didn't find \"%s\" in \"%s\"\n", needle, haystack); - return 1; - } +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ - return 0; +float +__x2y2m1f (float x, float y) +{ + double dx = x, dy = y; + return (float) ((dx - 1) * (dx + 1) + dy * dy); } - -#include "../test-skeleton.c" diff --git a/libc/sysdeps/ieee754/flt-32/s_sincosf.c b/libc/sysdeps/ieee754/flt-32/s_sincosf.c index 1b4d000e1..c3bd998ab 100644 --- a/libc/sysdeps/ieee754/flt-32/s_sincosf.c +++ b/libc/sysdeps/ieee754/flt-32/s_sincosf.c @@ -21,9 +21,14 @@ #include <math_private.h> +#ifndef SINCOSF +# define SINCOSF_FUNC __sincosf +#else +# define SINCOSF_FUNC SINCOSF +#endif void -__sincosf (float x, float *sinx, float *cosx) +SINCOSF_FUNC (float x, float *sinx, float *cosx) { int32_t ix; @@ -70,4 +75,7 @@ __sincosf (float x, float *sinx, float *cosx) } } } + +#ifndef SINCOSF weak_alias (__sincosf, sincosf) +#endif diff --git a/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h b/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h deleted file mode 100644 index 89b207331..000000000 --- a/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h +++ /dev/null @@ -1,50 +0,0 @@ -/* `HUGE_VALL' constant for IEEE 754 machines (where it is infinity). - Used by <stdlib.h> and <math.h> functions for overflow. - Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 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, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _MATH_H -# error "Never use <bits/huge_vall.h> directly; include <math.h> instead." -#endif - -/* IEEE positive infinity (-HUGE_VAL is negative infinity). */ - -#if __GNUC_PREREQ(3,3) -# define HUGE_VALL (__builtin_huge_vall()) -#elif __GNUC_PREREQ(2,96) -# define HUGE_VALL (__extension__ 0x1.0p32767L) -#else -# include <endian.h> - -typedef union { unsigned char __c[16]; long double __ld; } __huge_vall_t; - -# if __BYTE_ORDER == __BIG_ENDIAN -# define __HUGE_VALL_bytes { 0x7f, 0xff, 0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -# endif -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define __HUGE_VALL_bytes { 0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0xff, 0x7f } -# endif - -# ifdef __GNUC__ -# define HUGE_VALL (__extension__ \ - ((__huge_vall_t) { __c : __HUGE_VALL_bytes }).__ld) -# else -static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes }; -# define HUGE_VALL (__huge_vall.__ld) -# endif -#endif diff --git a/libc/sysdeps/ieee754/ldbl-128/s_fma.c b/libc/sysdeps/ieee754/ldbl-128/s_fma.c index 355b60ebb..b08ff29c0 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_fma.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_fma.c @@ -1,5 +1,5 @@ /* Compute x * y + z as ternary operation. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2010. @@ -33,6 +33,12 @@ __fma (double x, double y, double z) fenv_t env; /* Multiplication is always exact. */ long double temp = (long double) x * (long double) y; + + /* Ensure correct sign of an exact zero result by performing the + addition in the original rounding mode in that case. */ + if (temp == -z) + return (double) temp + z; + union ieee854_long_double u; feholdexcept (&env); fesetround (FE_TOWARDZERO); diff --git a/libc/sysdeps/ieee754/ldbl-128/s_fmal.c b/libc/sysdeps/ieee754/ldbl-128/s_fmal.c index 963bbd734..46b3d81ce 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_fmal.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_fmal.c @@ -50,6 +50,11 @@ __fmal (long double x, long double y, long double z) && u.ieee.exponent != 0x7fff && v.ieee.exponent != 0x7fff) return (z + x) + y; + /* If z is zero and x are y are nonzero, compute the result + as x * y to avoid the wrong sign of a zero result if x * y + underflows to 0. */ + if (z == 0 && x != 0 && y != 0) + return x * y; /* If x or y or z is Inf/NaN, or if fma will certainly overflow, or if x * y is less than half of LDBL_DENORM_MIN, compute as x * y + z. */ @@ -129,6 +134,11 @@ __fmal (long double x, long double y, long double z) y = v.d; z = w.d; } + + /* Ensure correct sign of exact 0 + 0. */ + if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0)) + return x * y + z; + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ #define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) long double x1 = x * C; diff --git a/libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c b/libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c new file mode 100644 index 000000000..a249cd347 --- /dev/null +++ b/libc/sysdeps/ieee754/ldbl-128/x2y2m1l.c @@ -0,0 +1,111 @@ +/* Compute x^2 + y^2 - 1, without large cancellation error. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <float.h> +#include <stdlib.h> + +/* Calculate X + Y exactly and store the result in *HI + *LO. It is + given that |X| >= |Y| and the values are small enough that no + overflow occurs. */ + +static inline void +add_split (long double *hi, long double *lo, long double x, long double y) +{ + /* Apply Dekker's algorithm. */ + *hi = x + y; + *lo = (x - *hi) + y; +} + +/* Calculate X * Y exactly and store the result in *HI + *LO. It is + given that the values are small enough that no overflow occurs and + large enough (or zero) that no underflow occurs. */ + +static inline void +mul_split (long double *hi, long double *lo, long double x, long double y) +{ +#ifdef __FP_FAST_FMAL + /* Fast built-in fused multiply-add. */ + *hi = x * y; + *lo = __builtin_fmal (x, y, -*hi); +#elif defined FP_FAST_FMAL + /* Fast library fused multiply-add, compiler before GCC 4.6. */ + *hi = x * y; + *lo = __fmal (x, y, -*hi); +#else + /* Apply Dekker's algorithm. */ + *hi = x * y; +# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) + long double x1 = x * C; + long double y1 = y * C; +# undef C + x1 = (x - x1) + x1; + y1 = (y - y1) + y1; + long double x2 = x - x1; + long double y2 = y - y1; + *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2; +#endif +} + +/* Compare absolute values of floating-point values pointed to by P + and Q for qsort. */ + +static int +compare (const void *p, const void *q) +{ + long double pld = fabsl (*(const long double *) p); + long double qld = fabsl (*(const long double *) q); + if (pld < qld) + return -1; + else if (pld == qld) + return 0; + else + return 1; +} + +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ + +long double +__x2y2m1l (long double x, long double y) +{ + long double vals[4]; + SET_RESTORE_ROUNDL (FE_TONEAREST); + mul_split (&vals[1], &vals[0], x, x); + mul_split (&vals[3], &vals[2], y, y); + if (x >= 0.75L) + vals[1] -= 1.0L; + else + { + vals[1] -= 0.5L; + vals[3] -= 0.5L; + } + qsort (vals, 4, sizeof (long double), compare); + /* Add up the values so that each element of VALS has absolute value + at most equal to the last set bit of the next nonzero + element. */ + for (size_t i = 0; i <= 2; i++) + { + add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]); + qsort (vals + i + 1, 3 - i, sizeof (long double), compare); + } + /* Now any error from this addition will be small. */ + return vals[3] + vals[2] + vals[1] + vals[0]; +} diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c b/libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c new file mode 100644 index 000000000..4379b68c3 --- /dev/null +++ b/libc/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c @@ -0,0 +1,128 @@ +/* Compute x^2 + y^2 - 1, without large cancellation error. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <float.h> + +/* Calculate X + Y exactly and store the result in *HI + *LO. It is + given that |X| >= |Y| and the values are small enough that no + overflow occurs. */ + +static inline void +add_split (double *hi, double *lo, double x, double y) +{ + /* Apply Dekker's algorithm. */ + *hi = x + y; + *lo = (x - *hi) + y; +} + +/* Calculate X * Y exactly and store the result in *HI + *LO. It is + given that the values are small enough that no overflow occurs and + large enough (or zero) that no underflow occurs. */ + +static inline void +mul_split (double *hi, double *lo, double x, double y) +{ +#ifdef __FP_FAST_FMA + /* Fast built-in fused multiply-add. */ + *hi = x * y; + *lo = __builtin_fma (x, y, -*hi); +#elif defined FP_FAST_FMA + /* Fast library fused multiply-add, compiler before GCC 4.6. */ + *hi = x * y; + *lo = __fma (x, y, -*hi); +#else + /* Apply Dekker's algorithm. */ + *hi = x * y; +# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1) + double x1 = x * C; + double y1 = y * C; +# undef C + x1 = (x - x1) + x1; + y1 = (y - y1) + y1; + double x2 = x - x1; + double y2 = y - y1; + *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2; +#endif +} + +/* Compare absolute values of floating-point values pointed to by P + and Q for qsort. */ + +static int +compare (const void *p, const void *q) +{ + double pd = fabs (*(const double *) p); + double qd = fabs (*(const double *) q); + if (pd < qd) + return -1; + else if (pd == qd) + return 0; + else + return 1; +} + +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ + +long double +__x2y2m1l (long double x, long double y) +{ + double vals[12]; + SET_RESTORE_ROUND (FE_TONEAREST); + union ibm_extended_long_double xu, yu; + xu.d = x; + yu.d = y; + if (fabs (xu.dd[1]) < 0x1p-500) + xu.dd[1] = 0.0; + if (fabs (yu.dd[1]) < 0x1p-500) + yu.dd[1] = 0.0; + mul_split (&vals[1], &vals[0], xu.dd[0], xu.dd[0]); + mul_split (&vals[3], &vals[2], xu.dd[0], xu.dd[1]); + vals[2] *= 2.0; + vals[3] *= 2.0; + mul_split (&vals[5], &vals[4], xu.dd[1], xu.dd[1]); + mul_split (&vals[7], &vals[6], yu.dd[0], yu.dd[0]); + mul_split (&vals[9], &vals[8], yu.dd[0], yu.dd[1]); + vals[8] *= 2.0; + vals[9] *= 2.0; + mul_split (&vals[11], &vals[10], yu.dd[1], yu.dd[1]); + if (xu.dd[0] >= 0.75) + vals[1] -= 1.0; + else + { + vals[1] -= 0.5; + vals[7] -= 0.5; + } + qsort (vals, 12, sizeof (double), compare); + /* Add up the values so that each element of VALS has absolute value + at most equal to the last set bit of the next nonzero + element. */ + for (size_t i = 0; i <= 10; i++) + { + add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]); + qsort (vals + i + 1, 11 - i, sizeof (double), compare); + } + /* Now any error from this addition will be small. */ + long double retval = (long double) vals[11]; + for (size_t i = 10; i != (size_t) -1; i--) + retval += (long double) vals[i]; + return retval; +} diff --git a/libc/sysdeps/ieee754/ldbl-96/s_fma.c b/libc/sysdeps/ieee754/ldbl-96/s_fma.c index 78c0b0db1..001d8063d 100644 --- a/libc/sysdeps/ieee754/ldbl-96/s_fma.c +++ b/libc/sysdeps/ieee754/ldbl-96/s_fma.c @@ -1,5 +1,5 @@ /* Compute x * y + z as ternary operation. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2010. @@ -38,6 +38,10 @@ __fma (double x, double y, double z) return (x * y) + z; } + /* Ensure correct sign of exact 0 + 0. */ + if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0)) + return x * y + z; + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ #define C ((1ULL << (LDBL_MANT_DIG + 1) / 2) + 1) long double x1 = (long double) x * C; diff --git a/libc/sysdeps/ieee754/ldbl-96/s_fmal.c b/libc/sysdeps/ieee754/ldbl-96/s_fmal.c index ca1e0905a..d12512428 100644 --- a/libc/sysdeps/ieee754/ldbl-96/s_fmal.c +++ b/libc/sysdeps/ieee754/ldbl-96/s_fmal.c @@ -50,6 +50,11 @@ __fmal (long double x, long double y, long double z) && u.ieee.exponent != 0x7fff && v.ieee.exponent != 0x7fff) return (z + x) + y; + /* If z is zero and x are y are nonzero, compute the result + as x * y to avoid the wrong sign of a zero result if x * y + underflows to 0. */ + if (z == 0 && x != 0 && y != 0) + return x * y; /* If x or y or z is Inf/NaN, or if fma will certainly overflow, or if x * y is less than half of LDBL_DENORM_MIN, compute as x * y + z. */ @@ -129,6 +134,11 @@ __fmal (long double x, long double y, long double z) y = v.d; z = w.d; } + + /* Ensure correct sign of exact 0 + 0. */ + if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0)) + return x * y + z; + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ #define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) long double x1 = x * C; diff --git a/libc/sysdeps/ieee754/ldbl-96/x2y2m1.c b/libc/sysdeps/ieee754/ldbl-96/x2y2m1.c new file mode 100644 index 000000000..3086fa2c8 --- /dev/null +++ b/libc/sysdeps/ieee754/ldbl-96/x2y2m1.c @@ -0,0 +1,39 @@ +/* Compute x^2 + y^2 - 1, without large cancellation error. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <float.h> + +#if FLT_EVAL_METHOD == 0 + +# include <sysdeps/ieee754/dbl-64/x2y2m1.c> + +#else + +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ + +double +__x2y2m1 (double x, double y) +{ + return (double) __x2y2m1l (x, y); +} + +#endif diff --git a/libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c b/libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c new file mode 100644 index 000000000..a249cd347 --- /dev/null +++ b/libc/sysdeps/ieee754/ldbl-96/x2y2m1l.c @@ -0,0 +1,111 @@ +/* Compute x^2 + y^2 - 1, without large cancellation error. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <math.h> +#include <math_private.h> +#include <float.h> +#include <stdlib.h> + +/* Calculate X + Y exactly and store the result in *HI + *LO. It is + given that |X| >= |Y| and the values are small enough that no + overflow occurs. */ + +static inline void +add_split (long double *hi, long double *lo, long double x, long double y) +{ + /* Apply Dekker's algorithm. */ + *hi = x + y; + *lo = (x - *hi) + y; +} + +/* Calculate X * Y exactly and store the result in *HI + *LO. It is + given that the values are small enough that no overflow occurs and + large enough (or zero) that no underflow occurs. */ + +static inline void +mul_split (long double *hi, long double *lo, long double x, long double y) +{ +#ifdef __FP_FAST_FMAL + /* Fast built-in fused multiply-add. */ + *hi = x * y; + *lo = __builtin_fmal (x, y, -*hi); +#elif defined FP_FAST_FMAL + /* Fast library fused multiply-add, compiler before GCC 4.6. */ + *hi = x * y; + *lo = __fmal (x, y, -*hi); +#else + /* Apply Dekker's algorithm. */ + *hi = x * y; +# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) + long double x1 = x * C; + long double y1 = y * C; +# undef C + x1 = (x - x1) + x1; + y1 = (y - y1) + y1; + long double x2 = x - x1; + long double y2 = y - y1; + *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2; +#endif +} + +/* Compare absolute values of floating-point values pointed to by P + and Q for qsort. */ + +static int +compare (const void *p, const void *q) +{ + long double pld = fabsl (*(const long double *) p); + long double qld = fabsl (*(const long double *) q); + if (pld < qld) + return -1; + else if (pld == qld) + return 0; + else + return 1; +} + +/* Return X^2 + Y^2 - 1, computed without large cancellation error. + It is given that 1 > X >= Y >= epsilon / 2, and that either X >= + 0.75 or Y >= 0.5. */ + +long double +__x2y2m1l (long double x, long double y) +{ + long double vals[4]; + SET_RESTORE_ROUNDL (FE_TONEAREST); + mul_split (&vals[1], &vals[0], x, x); + mul_split (&vals[3], &vals[2], y, y); + if (x >= 0.75L) + vals[1] -= 1.0L; + else + { + vals[1] -= 0.5L; + vals[3] -= 0.5L; + } + qsort (vals, 4, sizeof (long double), compare); + /* Add up the values so that each element of VALS has absolute value + at most equal to the last set bit of the next nonzero + element. */ + for (size_t i = 0; i <= 2; i++) + { + add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]); + qsort (vals + i + 1, 3 - i, sizeof (long double), compare); + } + /* Now any error from this addition will be small. */ + return vals[3] + vals[2] + vals[1] + vals[0]; +} diff --git a/libc/sysdeps/ieee754/ldbl-opt/configure b/libc/sysdeps/ieee754/ldbl-opt/configure index d1f3177cf..6e69038b9 100755 --- a/libc/sysdeps/ieee754/ldbl-opt/configure +++ b/libc/sysdeps/ieee754/ldbl-opt/configure @@ -1,123 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/ieee754/ldbl-opt/. diff --git a/libc/sysdeps/mach/configure b/libc/sysdeps/mach/configure index b41449e80..33cf09bd7 100644 --- a/libc/sysdeps/mach/configure +++ b/libc/sysdeps/mach/configure @@ -1,102 +1,4 @@ -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # ac_fn_c_try_cpp LINENO # ---------------------- @@ -288,45 +190,7 @@ $as_echo_n "checking for task_t in mach/mach_types.h... " >&6; } if ${libc_cv_mach_task_t+:} false; then : $as_echo_n "(cached) " >&6 else - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <mach/mach_types.h> int diff --git a/libc/sysdeps/mach/hurd/_G_config.h b/libc/sysdeps/mach/hurd/_G_config.h deleted file mode 100644 index b3a7db72a..000000000 --- a/libc/sysdeps/mach/hurd/_G_config.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is needed by libio to define various configuration parameters. - These are always the same in the GNU C library. */ - -#ifndef _G_config_h -#define _G_config_h 1 - -/* Define types for libio in terms of the standard internal type names. */ - -#include <bits/types.h> -#define __need_size_t -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define __need_wchar_t -#endif -#define __need_NULL -#include <stddef.h> -#define __need_mbstate_t -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define __need_wint_t -#endif -#include <wchar.h> -typedef struct -{ - __off_t __pos; - __mbstate_t __state; -} _G_fpos_t; -typedef struct -{ - __off64_t __pos; - __mbstate_t __state; -} _G_fpos64_t; -#define _G_off64_t __off64_t -#define _G_stat64 stat64 -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# include <gconv.h> -typedef union -{ - struct __gconv_info __cd; - struct - { - struct __gconv_info __cd; - struct __gconv_step_data __data; - } __combined; -} _G_iconv_t; -#endif - - -/* These library features are always available in the GNU C library. */ -#define _G_va_list __gnuc_va_list - -#define _G_HAVE_MMAP 1 - -#define _G_IO_IO_FILE_VERSION 0x20001 - -#define _G_OPEN64 __open64 -#define _G_LSEEK64 __lseek64 -#define _G_MMAP64 __mmap64 -#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf) - -/* This is defined by <bits/stat.h> if `st_blksize' exists. */ -#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE) - -#define _G_BUFSIZ 8192 - -#endif /* _G_config.h */ diff --git a/libc/sysdeps/mach/hurd/bits/typesizes.h b/libc/sysdeps/mach/hurd/bits/typesizes.h index efc13143e..af132669f 100644 --- a/libc/sysdeps/mach/hurd/bits/typesizes.h +++ b/libc/sysdeps/mach/hurd/bits/typesizes.h @@ -51,7 +51,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SLONGWORD_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE __S32_TYPE diff --git a/libc/sysdeps/mach/hurd/configure b/libc/sysdeps/mach/hurd/configure index 3c90a665a..84948a549 100755 --- a/libc/sysdeps/mach/hurd/configure +++ b/libc/sysdeps/mach/hurd/configure @@ -1,128 +1,5 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile # This file is generated from configure.in by Autoconf. DO NOT EDIT! -# GNU libc on the Hurd is always reentrant. -DEFINES="$DEFINES -D_LIBC_REENTRANT" - $as_echo "#define NO_HIDDEN 1" >>confdefs.h diff --git a/libc/sysdeps/mach/hurd/dl-sysdep.c b/libc/sysdeps/mach/hurd/dl-sysdep.c index 13b001043..fad388b73 100644 --- a/libc/sysdeps/mach/hurd/dl-sysdep.c +++ b/libc/sysdeps/mach/hurd/dl-sysdep.c @@ -646,26 +646,6 @@ _dl_show_auxv (void) } -/* Return an array of useful/necessary hardware capability names. */ -const struct r_strlenpair * -internal_function -_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, - size_t *max_capstrlen) -{ - struct r_strlenpair *result; - - /* Return an empty array. Hurd has no hardware capabilities. */ - result = (struct r_strlenpair *) malloc (sizeof (*result)); - if (result == NULL) - _dl_signal_error (ENOMEM, NULL, NULL, "cannot create capability list"); - - result[0].str = (char *) result; /* Does not really matter. */ - result[0].len = 0; - - *sz = 1; - return result; -} - void weak_function _dl_init_first (int argc, ...) { diff --git a/libc/sysdeps/mach/hurd/malloc-machine.h b/libc/sysdeps/mach/hurd/malloc-machine.h index 4a8bd16e6..16e054fe5 100644 --- a/libc/sysdeps/mach/hurd/malloc-machine.h +++ b/libc/sysdeps/mach/hurd/malloc-machine.h @@ -66,8 +66,9 @@ __libc_tsd_define (static, void *, MALLOC) /* declaration/common definition */ #include <sys/mman.h> -#undef madvise -#define madvise(addr, len, advice) ((void) (addr), (void) (len), (void) (advice)) +#undef __madvise +#define __madvise(addr, len, advice) \ + ((void) (addr), (void) (len), (void) (advice)) #include <sysdeps/generic/malloc-machine.h> diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c index 05883bd55..672571ef2 100644 --- a/libc/sysdeps/posix/getaddrinfo.c +++ b/libc/sysdeps/posix/getaddrinfo.c @@ -1369,10 +1369,6 @@ static const struct scopeentry /* Link-local addresses: scope 2. */ { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 }, { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 }, - /* Site-local addresses: scope 5. */ - { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 }, - { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 }, - { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 }, /* Default: scope 14. */ { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 } }; diff --git a/libc/sysdeps/posix/sleep.c b/libc/sysdeps/posix/sleep.c index dfd7420ac..b3c9e27f1 100644 --- a/libc/sysdeps/posix/sleep.c +++ b/libc/sysdeps/posix/sleep.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc. +/* Sleep for a given number of seconds. POSIX.1 version. + Copyright (C) 1991-2012 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 @@ -15,20 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <signal.h> #include <time.h> #include <unistd.h> #include <errno.h> +#include <sys/param.h> -/* SIGALRM signal handler for `sleep'. This does nothing but return, - but SIG_IGN isn't supposed to break `pause'. */ -static void -sleep_handler (int sig) -{ - return; -} - /* Make the process sleep for SECONDS seconds, or until a signal arrives and is not ignored. The function returns the number of seconds less than SECONDS which it actually slept (zero if it slept the full time). @@ -39,67 +32,44 @@ sleep_handler (int sig) unsigned int __sleep (unsigned int seconds) { - unsigned int remaining, slept; - time_t before, after; - sigset_t set, oset; - struct sigaction act, oact; - int save = errno; - - if (seconds == 0) - return 0; - - /* Block SIGALRM signals while frobbing the handler. */ - if (sigemptyset (&set) < 0 || - sigaddset (&set, SIGALRM) < 0 || - sigprocmask (SIG_BLOCK, &set, &oset)) - return seconds; - - act.sa_handler = sleep_handler; - act.sa_flags = 0; - act.sa_mask = oset; /* execute handler with original mask */ - if (sigaction (SIGALRM, &act, &oact) < 0) - return seconds; - - before = time ((time_t *) NULL); - remaining = alarm (seconds); - - if (remaining > 0 && remaining < seconds) + /* This is not necessary but some buggy programs depend on it. */ + if (__builtin_expect (seconds == 0, 0)) { - /* The user's alarm will expire before our own would. - Restore the user's signal action state and let his alarm happen. */ - (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL); - alarm (remaining); /* Restore sooner alarm. */ - sigsuspend (&oset); /* Wait for it to go off. */ - after = time ((time_t *) NULL); +#ifdef CANCELLATION_P + CANCELLATION_P (THREAD_SELF); +#endif + return 0; } - else - { - /* Atomically restore the old signal mask - (which had better not block SIGALRM), - and wait for a signal to arrive. */ - sigsuspend (&oset); - after = time ((time_t *) NULL); + int save_errno = errno; - /* Restore the old signal action state. */ - (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL); + const unsigned int max + = (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1); + struct timespec ts = { 0, 0 }; + do + { + if (sizeof (ts.tv_sec) <= sizeof (seconds)) + { + /* Since SECONDS is unsigned assigning the value to .tv_sec can + overflow it. In this case we have to wait in steps. */ + ts.tv_sec += MIN (seconds, max); + seconds -= (unsigned int) ts.tv_sec; + } + else + { + ts.tv_sec = (time_t) seconds; + seconds = 0; + } + + if (__nanosleep (&ts, &ts) < 0) + /* We were interrupted. + Return the number of (whole) seconds we have not yet slept. */ + return seconds + ts.tv_sec; } + while (seconds > 0); - /* Notice how long we actually slept. */ - slept = after - before; - - /* Restore the user's alarm if we have not already past it. - If we have, be sure to turn off the alarm in case a signal - other than SIGALRM was what woke us up. */ - (void) alarm (remaining > slept ? remaining - slept : 0); - - /* Restore the original signal mask. */ - (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); - - /* Restore the `errno' value we started with. - Some of the calls we made might have failed, but we didn't care. */ - __set_errno (save); + __set_errno (save_errno); - return slept > seconds ? 0 : seconds - slept; + return 0; } weak_alias (__sleep, sleep) diff --git a/libc/sysdeps/posix/sysconf.c b/libc/sysdeps/posix/sysconf.c index d9b3c83ab..bfe28b47e 100644 --- a/libc/sysdeps/posix/sysconf.c +++ b/libc/sysdeps/posix/sysconf.c @@ -1227,6 +1227,7 @@ __sysconf (name) case _SC_LEVEL3_CACHE_LINESIZE: case _SC_LEVEL4_CACHE_SIZE: case _SC_LEVEL4_CACHE_ASSOC: + case _SC_LEVEL4_CACHE_LINESIZE: /* In general we cannot determine these values. Therefore we return zero which indicates that no information is available. */ diff --git a/libc/sysdeps/powerpc/configure b/libc/sysdeps/powerpc/configure index c3ad67f01..4afbc29ab 100755 --- a/libc/sysdeps/powerpc/configure +++ b/libc/sysdeps/powerpc/configure @@ -1,85 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/powerpc. diff --git a/libc/sysdeps/powerpc/powerpc32/configure b/libc/sysdeps/powerpc/powerpc32/configure index 86ecfdcf4..31c571d9a 100644 --- a/libc/sysdeps/powerpc/powerpc32/configure +++ b/libc/sysdeps/powerpc/powerpc32/configure @@ -1,85 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/powerpc/powerpc32. diff --git a/libc/sysdeps/powerpc/powerpc64/configure b/libc/sysdeps/powerpc/powerpc64/configure index 7cff76141..5ddac5592 100644 --- a/libc/sysdeps/powerpc/powerpc64/configure +++ b/libc/sysdeps/powerpc/powerpc64/configure @@ -1,85 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/powerpc/powerpc64. diff --git a/libc/sysdeps/powerpc/sys/platform/ppc.h b/libc/sysdeps/powerpc/sys/platform/ppc.h index 165652c7c..3780f57ba 100644 --- a/libc/sysdeps/powerpc/sys/platform/ppc.h +++ b/libc/sysdeps/powerpc/sys/platform/ppc.h @@ -20,6 +20,7 @@ #define _SYS_PLATFORM_PPC_H 1 #include <stdint.h> +#include <bits/ppc.h> /* Read the Time Base Register. */ static inline uint64_t diff --git a/libc/sysdeps/pthread/aio_fsync.c b/libc/sysdeps/pthread/aio_fsync.c index 046e25c17..5b5d1863e 100644 --- a/libc/sysdeps/pthread/aio_fsync.c +++ b/libc/sysdeps/pthread/aio_fsync.c @@ -46,7 +46,7 @@ aio_fsync (int op, struct aiocb *aiocbp) flags = fcntl (aiocbp->aio_fildes, F_GETFL); if (__builtin_expect (flags == -1, 0) - || __builtin_expect ((flags & (O_RDWR | O_WRONLY)) == 0, 0)) + || __builtin_expect ((flags & O_ACCMODE) == O_RDONLY, 0)) { __set_errno (EBADF); return -1; diff --git a/libc/sysdeps/s390/s390-32/configure b/libc/sysdeps/s390/s390-32/configure index e982e817f..669bb9be5 100644 --- a/libc/sysdeps/s390/s390-32/configure +++ b/libc/sysdeps/s390/s390-32/configure @@ -2,3 +2,4 @@ # Local configure fragment for sysdeps/s390. $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + diff --git a/libc/sysdeps/s390/s390-64/configure b/libc/sysdeps/s390/s390-64/configure index e982e817f..669bb9be5 100644 --- a/libc/sysdeps/s390/s390-64/configure +++ b/libc/sysdeps/s390/s390-64/configure @@ -2,3 +2,4 @@ # Local configure fragment for sysdeps/s390. $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + diff --git a/libc/sysdeps/sh/configure b/libc/sysdeps/sh/configure index 655668556..b0f3b2fa2 100644 --- a/libc/sysdeps/sh/configure +++ b/libc/sysdeps/sh/configure @@ -2,3 +2,4 @@ # Local configure fragment for sysdeps/sh. $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + diff --git a/libc/sysdeps/sh/init-first.c b/libc/sysdeps/sh/init-first.c deleted file mode 100644 index f298724c1..000000000 --- a/libc/sysdeps/sh/init-first.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. For SH. - Copyright (C) 1995-2012 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, see - <http://www.gnu.org/licenses/>. */ - -#include <ctype.h> -#include <unistd.h> - -extern void __libc_init (int, char **, char **); -#ifdef USE_NONOPTION_FLAGS -extern void __getopt_clean_environment (char **); -#endif -extern void __libc_global_ctors (void); - -int __libc_multiple_libcs attribute_hidden = 1; - -static void -init (int *data) -{ - int argc = *data; - char **argv = (void *) (data + 1); - char **envp = &argv[argc + 1]; - - __environ = envp; - __libc_init (argc, argv, envp); - -#ifdef USE_NONOPTION_FLAGS - /* This is a hack to make the special getopt in GNU libc working. */ - __getopt_clean_environment (envp); -#endif - - /* Initialize ctype data. */ - __ctype_init (); -} - -#ifdef SHARED -/* This function is called to initialize the shared C library. - It is called just before the user _start code from sh/sh[34]/start.S, - with the stack set up as that code gets it. */ - -/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT - pointer in the dynamic section based solely on that. It is convention - for this function to be in the `.init' section, but the symbol name is - the only thing that really matters!! */ -/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ - -void -_init (int argc, ...) -{ - init (&argc); - -#ifndef NO_CTORS_DTORS_SECTIONS - __libc_global_ctors (); -#endif -} -#endif - - -void -__libc_init_first (int argc __attribute__ ((unused)), ...) -{ -#ifndef SHARED - init (&argc); -#endif -} diff --git a/libc/sysdeps/sparc/configure b/libc/sysdeps/sparc/configure index 72b4622af..3abba2750 100644 --- a/libc/sysdeps/sparc/configure +++ b/libc/sysdeps/sparc/configure @@ -1,85 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/sparc. diff --git a/libc/sysdeps/sparc/fpu/libm-test-ulps b/libc/sysdeps/sparc/fpu/libm-test-ulps index b7dc3b483..0f8179f6b 100644 --- a/libc/sysdeps/sparc/fpu/libm-test-ulps +++ b/libc/sysdeps/sparc/fpu/libm-test-ulps @@ -876,6 +876,9 @@ float: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i": +float: 1 +ifloat: 1 Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i": float: 1 ifloat: 1 @@ -903,6 +906,9 @@ ldouble: 1 Test "Real part of: clog (0x1.fp+16383 - 0x1p-16494 i) == 11356.49165759582936919077408168801636572 - 0 i": ildouble: 1 ldouble: 1 +Test "Imaginary part of: clog (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 3.2047474274603604594851472963586149973093e-29 + 1.4422922682185099608731642353544207976604 i": +ildouble: 1 +ldouble: 1 Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i": double: 1 idouble: 1 @@ -927,6 +933,50 @@ ldouble: 1 Test "Real part of: clog (0x1p-16494 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i": ildouble: 1 ldouble: 1 +Test "Imaginary part of: clog (0x2818p-15 + 0x798fp-15 i) == 1.5366822245016167178749091974664853785194e-08 + 1.2522014929038946066987318471922169174157 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x298c62cb546588a7p-63 + 0x7911b1dfcc4ecdaep-63 i) == -1.1931267660846218205882675852805793644095e-36 + 1.2402109774337032400594953899784058127412 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x2ede88p-23 + 0x771c3fp-23 i) == -4.4764192352906350039050902870893173560494e-13 + 1.1959106857549200806818600493552847793381 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x3f96469050f650869c2p-75 + 0x6f16b2c9c8b05988335p-75 i) == -1.0509738482436128031927971874674370984602e-45 + 1.0509191467640012308402149909370784281448 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x55cb6d0c83af5p-55 + 0x7fe33c0c7c4e90p-55 i) == -5.2000108498455368032511404449795741611813e-32 + 1.5288921536982513453421343495466824420259 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 8.3076914081087805757422664530653247447136e-30 + 1.2072712126771536614482822173033535043206 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x659feap-24 + 0xeaf6f9p-24 i) == 3.7303493627403868207597214252239749960738e-14 + 1.1625816408046866464773042283673653469061 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x6771f22c64ed551b857c128b4cp-105 + 0x1f570e7a13cc3cf2f44fd793ea1p-105 i) == -1.4281333889622737316199756373421183559948e-62 + 1.3673546561165378090903506783353927980633 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 2.4244570985709679851855191080208817099132e-37 + 1.1393074519572050614551047548718495655972 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -9.7375017988218644730510244778042114638107e-30 + 0.9790637929494922564724108399524154766631 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0x9b57bp-20 + 0xcb7b4p-20 i) == -3.9563019528687610863490232935890272740908e-11 + 0.9187593477446338910857133065497364950682 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0xdb85c467ee2aadd5f425fe0f4b8dp-114 + 0x3e83162a0f95f1dcbf97dddf410eap-114 i) == 4.6017338806965821566734340588575402712716e-67 + 1.3547418904611758959096647942223384691728 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0xfd95243681c055c2632286921092p-113 + 0x1bccabcd29ca2152860ec29e34ef7p-113 i) == 6.6255694866654064502633121109394710807528e-66 + 1.0526409614996288387567810726095850312049 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 5.3718272201930019901317065495843842735179e-26 + 1.0503831592447830576186444373011142397404 i": +ildouble: 1 +ldouble: 1 Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i": float: 1 ifloat: 1 @@ -1046,6 +1096,16 @@ ifloat: 1 Test "Imaginary part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "Real part of: clog10 (0x1.00000000000000123456789abcp0 + 0x1.23456789p-1000 i) == 4.285899851347756186652871946325962330640e-19 + 4.611541215247321502041995872887317363241e-302 i": ildouble: 1 ldouble: 1 @@ -1103,6 +1163,37 @@ ldouble: 1 Test "Real part of: clog10 (0x1.fp+16383 + 0x1p+16383 i) == 4932.112944269463028900262609694408579449 + 0.2069271710841128115912940666587802677383 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0x1415bcaf2105940d49a636e98ae59p-115 + 0x7e6a150adfcd1b0921d44b31f40f4p-115 i) == 1.1288799405048268615023706955013387413519e-67 + 0.6137587762850841972073301550420510507903 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x15cfbd1990d1ffp-53 + 0x176a3973e09a9ap-53 i) == 4.4163015461643576961232672330852798804976e-31 + 0.3564851427422832755956993418877523303529 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0x1df515eb171a808b9e400266p-95 + 0x7c71eb0cd4688dfe98581c77p-95 i) == -1.5221162575729652613635150540947625639689e-57 + 0.5795934880811949230121092882659698986043 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x1df515eb171a808b9e400266p-95 + 0x7c71eb0cd4688dfe98581c77p-95 i) == -1.5221162575729652613635150540947625639689e-57 + 0.5795934880811949230121092882659698986043 i": +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i": double: 1 idouble: 1 @@ -1162,6 +1253,88 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x3f96469050f650869c2p-75 + 0x6f16b2c9c8b05988335p-75 i) == -4.5643214291682663316715446865040356750881e-46 + 0.4564083863660793840592614609053162690362 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x4d9c37e2b5cb4533p-63 + 0x65c98be2385a042ep-63 i) == 2.7822833698845776001753149807484078521508e-37 + 0.3992725998539071066769046272515417679815 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x55cb6d0c83af5p-55 + 0x7fe33c0c7c4e90p-55 i) == -2.2583360179249556400630343805573865814771e-32 + 0.6639894257763289307423302343317622430835 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x602fd5037c4792efp-64 + 0xed3e2086dcca80b8p-64 i) == -1.0146400362652473358437501879334790111898e-37 + 0.5149047982335273098246594109614460842099 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x6241ef0da53f539f02fad67dabp-106 + 0x3fb46641182f7efd9caa769dac0p-106 i) == 1.8804859395820231849002915747252695375405e-63 + 0.6404513901551516189871978418046651877394 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0xdb85c467ee2aadd5f425fe0f4b8dp-114 + 0x3e83162a0f95f1dcbf97dddf410eap-114 i) == 1.9985076315737626043096596036300177494613e-67 + 0.5883569274304683249184005177865521205198 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0xfd95243681c055c2632286921092p-113 + 0x1bccabcd29ca2152860ec29e34ef7p-113 i) == 2.8774482675253468630312378575186855052697e-66 + 0.4571561610046221605554903008571429975493 i": +ldouble: 2 +ildouble: 2 +Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i": double: 1 idouble: 1 @@ -3051,9 +3224,9 @@ ldouble: 1 Function: Real part of "clog10": double: 2 -float: 1 +float: 2 idouble: 2 -ifloat: 1 +ifloat: 2 ildouble: 1 ldouble: 1 diff --git a/libc/sysdeps/sparc/sparc32/dl-machine.h b/libc/sysdeps/sparc/sparc32/dl-machine.h index 2dfeeb27a..04ce7854a 100644 --- a/libc/sysdeps/sparc/sparc32/dl-machine.h +++ b/libc/sysdeps/sparc/sparc32/dl-machine.h @@ -29,11 +29,6 @@ #include <tls.h> #include <dl-plt.h> -#ifndef VALIDX -# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALTAGIDX (tag)) -#endif - /* Return nonzero iff ELF header is compatible with the running host. */ static inline int elf_machine_matches_host (const Elf32_Ehdr *ehdr) diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile index 4d45042a9..7358bdb16 100644 --- a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile +++ b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile @@ -1,4 +1,4 @@ ifeq ($(subdir),string) sysdep_routines += memcpy-ultra3 memcpy-niagara1 memcpy-niagara2 \ - memset-niagara1 + memset-niagara1 memcpy-niagara4 memset-niagara4 endif diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S new file mode 100644 index 000000000..75ef9c017 --- /dev/null +++ b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/memcpy-niagara4.S> diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S new file mode 100644 index 000000000..6545019c4 --- /dev/null +++ b/libc/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/memset-niagara4.S> diff --git a/libc/sysdeps/sparc/sparc64/dl-machine.h b/libc/sysdeps/sparc/sparc64/dl-machine.h index 35c24d155..dec2fa080 100644 --- a/libc/sysdeps/sparc/sparc64/dl-machine.h +++ b/libc/sysdeps/sparc/sparc64/dl-machine.h @@ -27,11 +27,6 @@ #include <sysdep.h> #include <dl-plt.h> -#ifndef VALIDX -# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALTAGIDX (tag)) -#endif - #define ELF64_R_TYPE_ID(info) ((info) & 0xff) #define ELF64_R_TYPE_DATA(info) ((info) >> 8) @@ -458,7 +453,14 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, break; case R_SPARC_JMP_IREL: value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap)); - /* Fall thru */ + /* 'high' is always zero, for large PLT entries the linker + emits an R_SPARC_IRELATIVE. */ +#ifdef RESOLVE_CONFLICT_FIND_MAP + sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0); +#else + sparc64_fixup_plt (map, reloc, reloc_addr, value, 0, 0); +#endif + break; case R_SPARC_JMP_SLOT: #ifdef RESOLVE_CONFLICT_FIND_MAP /* R_SPARC_JMP_SLOT conflicts against .plt[32768+] diff --git a/libc/sysdeps/sparc/sparc64/multiarch/Makefile b/libc/sysdeps/sparc/sparc64/multiarch/Makefile index 4d45042a9..7358bdb16 100644 --- a/libc/sysdeps/sparc/sparc64/multiarch/Makefile +++ b/libc/sysdeps/sparc/sparc64/multiarch/Makefile @@ -1,4 +1,4 @@ ifeq ($(subdir),string) sysdep_routines += memcpy-ultra3 memcpy-niagara1 memcpy-niagara2 \ - memset-niagara1 + memset-niagara1 memcpy-niagara4 memset-niagara4 endif diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S b/libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S new file mode 100644 index 000000000..3da98a87a --- /dev/null +++ b/libc/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S @@ -0,0 +1,332 @@ +/* Copy SIZE bytes from SRC to DEST. For SUN4V Niagara-4. + Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller (davem@davemloft.net) + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 + +#define FPRS_FEF 0x04 + +/* On T4 it is very expensive to access ASRs like %fprs and + * %asi, avoiding a read or a write can save ~50 cycles. + */ +#define FPU_ENTER \ + rd %fprs, %o5; \ + andcc %o5, FPRS_FEF, %g0; \ + be,a,pn %icc, 999f; \ + wr %g0, FPRS_FEF, %fprs; \ + 999: + +#define VISEntryHalf FPU_ENTER +#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs + +#define GLOBAL_SPARE %g5 + +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P +#define EX_LD(x) x +#define EX_ST(x) x +#define EX_RETVAL(x) x +#define LOAD(type,addr,dest) type [addr], dest +#define STORE(type,src,addr) type src, [addr] +#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI + +#if !defined NOT_IN_libc + + .register %g2,#scratch + .register %g3,#scratch + .register %g6,#scratch + + .text + +ENTRY(__mempcpy_niagara4) + ba,pt %icc, 101f + add %o0, %o2, %o3 +END(__mempcpy_niagara4) + + .align 32 +ENTRY(__memcpy_niagara4) +100: /* %o0=dst, %o1=src, %o2=len */ + mov %o0, %o3 +101: +#ifndef __arch64__ + srl %o2, 0, %o2 +#endif + brz,pn %o2, .Lexit + cmp %o2, 3 + ble,pn %icc, .Ltiny + cmp %o2, 19 + ble,pn %icc, .Lsmall + or %o0, %o1, %g2 + cmp %o2, 128 + bl,pn %icc, .Lmedium + nop + +.Llarge:/* len >= 0x80 */ + /* First get dest 8 byte aligned. */ + sub %g0, %o0, %g1 + and %g1, 0x7, %g1 + brz,pt %g1, 51f + sub %o2, %g1, %o2 + +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2)) + add %o1, 1, %o1 + subcc %g1, 1, %g1 + add %o0, 1, %o0 + bne,pt %icc, 1b + EX_ST(STORE(stb, %g2, %o0 - 0x01)) + +51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong) + LOAD(prefetch, %o1 + 0x080, #n_reads_strong) + LOAD(prefetch, %o1 + 0x0c0, #n_reads_strong) + LOAD(prefetch, %o1 + 0x100, #n_reads_strong) + LOAD(prefetch, %o1 + 0x140, #n_reads_strong) + LOAD(prefetch, %o1 + 0x180, #n_reads_strong) + LOAD(prefetch, %o1 + 0x1c0, #n_reads_strong) + LOAD(prefetch, %o1 + 0x200, #n_reads_strong) + + /* Check if we can use the straight fully aligned + * loop, or we require the alignaddr/faligndata variant. + */ + andcc %o1, 0x7, %o5 + bne,pn %icc, .Llarge_src_unaligned + sub %g0, %o0, %g1 + + /* Legitimize the use of initializing stores by getting dest + * to be 64-byte aligned. + */ + and %g1, 0x3f, %g1 + brz,pt %g1, .Llarge_aligned + sub %o2, %g1, %o2 + +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2)) + add %o1, 8, %o1 + subcc %g1, 8, %g1 + add %o0, 8, %o0 + bne,pt %icc, 1b + EX_ST(STORE(stx, %g2, %o0 - 0x08)) + +.Llarge_aligned: + /* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */ + andn %o2, 0x3f, %o4 + sub %o2, %o4, %o2 + +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1)) + add %o1, 0x40, %o1 + EX_LD(LOAD(ldx, %o1 - 0x38, %g2)) + subcc %o4, 0x40, %o4 + EX_LD(LOAD(ldx, %o1 - 0x30, %g3)) + EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE)) + EX_LD(LOAD(ldx, %o1 - 0x20, %o5)) + EX_ST(STORE_INIT(%g1, %o0)) + add %o0, 0x08, %o0 + EX_ST(STORE_INIT(%g2, %o0)) + add %o0, 0x08, %o0 + EX_LD(LOAD(ldx, %o1 - 0x18, %g2)) + EX_ST(STORE_INIT(%g3, %o0)) + add %o0, 0x08, %o0 + EX_LD(LOAD(ldx, %o1 - 0x10, %g3)) + EX_ST(STORE_INIT(GLOBAL_SPARE, %o0)) + add %o0, 0x08, %o0 + EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE)) + EX_ST(STORE_INIT(%o5, %o0)) + add %o0, 0x08, %o0 + EX_ST(STORE_INIT(%g2, %o0)) + add %o0, 0x08, %o0 + EX_ST(STORE_INIT(%g3, %o0)) + add %o0, 0x08, %o0 + EX_ST(STORE_INIT(GLOBAL_SPARE, %o0)) + add %o0, 0x08, %o0 + bne,pt %icc, 1b + LOAD(prefetch, %o1 + 0x200, #n_reads_strong) + + membar #StoreLoad | #StoreStore + + brz,pn %o2, .Lexit + cmp %o2, 19 + ble,pn %icc, .Lsmall_unaligned + nop + ba,a,pt %icc, .Lmedium_noprefetch + +.Lexit: retl + mov EX_RETVAL(%o3), %o0 + +.Llarge_src_unaligned: + andn %o2, 0x3f, %o4 + sub %o2, %o4, %o2 + VISEntryHalf + alignaddr %o1, %g0, %g1 + add %o1, %o4, %o1 + EX_LD(LOAD(ldd, %g1 + 0x00, %f0)) +1: EX_LD(LOAD(ldd, %g1 + 0x08, %f2)) + subcc %o4, 0x40, %o4 + EX_LD(LOAD(ldd, %g1 + 0x10, %f4)) + EX_LD(LOAD(ldd, %g1 + 0x18, %f6)) + EX_LD(LOAD(ldd, %g1 + 0x20, %f8)) + EX_LD(LOAD(ldd, %g1 + 0x28, %f10)) + EX_LD(LOAD(ldd, %g1 + 0x30, %f12)) + EX_LD(LOAD(ldd, %g1 + 0x38, %f14)) + faligndata %f0, %f2, %f16 + EX_LD(LOAD(ldd, %g1 + 0x40, %f0)) + faligndata %f2, %f4, %f18 + add %g1, 0x40, %g1 + faligndata %f4, %f6, %f20 + faligndata %f6, %f8, %f22 + faligndata %f8, %f10, %f24 + faligndata %f10, %f12, %f26 + faligndata %f12, %f14, %f28 + faligndata %f14, %f0, %f30 + EX_ST(STORE(std, %f16, %o0 + 0x00)) + EX_ST(STORE(std, %f18, %o0 + 0x08)) + EX_ST(STORE(std, %f20, %o0 + 0x10)) + EX_ST(STORE(std, %f22, %o0 + 0x18)) + EX_ST(STORE(std, %f24, %o0 + 0x20)) + EX_ST(STORE(std, %f26, %o0 + 0x28)) + EX_ST(STORE(std, %f28, %o0 + 0x30)) + EX_ST(STORE(std, %f30, %o0 + 0x38)) + add %o0, 0x40, %o0 + bne,pt %icc, 1b + LOAD(prefetch, %g1 + 0x200, #n_reads_strong) + VISExitHalf + + brz,pn %o2, .Lexit + cmp %o2, 19 + ble,pn %icc, .Lsmall_unaligned + nop + ba,a,pt %icc, .Lmedium_unaligned + +.Lmedium: + LOAD(prefetch, %o1 + 0x40, #n_reads_strong) + andcc %g2, 0x7, %g0 + bne,pn %icc, .Lmedium_unaligned + nop +.Lmedium_noprefetch: + andncc %o2, 0x20 - 1, %o5 + be,pn %icc, 2f + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1)) + EX_LD(LOAD(ldx, %o1 + 0x08, %g2)) + EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE)) + EX_LD(LOAD(ldx, %o1 + 0x18, %o4)) + add %o1, 0x20, %o1 + subcc %o5, 0x20, %o5 + EX_ST(STORE(stx, %g1, %o0 + 0x00)) + EX_ST(STORE(stx, %g2, %o0 + 0x08)) + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10)) + EX_ST(STORE(stx, %o4, %o0 + 0x18)) + bne,pt %icc, 1b + add %o0, 0x20, %o0 +2: andcc %o2, 0x18, %o5 + be,pt %icc, 3f + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1)) + add %o1, 0x08, %o1 + add %o0, 0x08, %o0 + subcc %o5, 0x08, %o5 + bne,pt %icc, 1b + EX_ST(STORE(stx, %g1, %o0 - 0x08)) +3: brz,pt %o2, .Lexit + cmp %o2, 0x04 + bl,pn %icc, .Ltiny + nop + EX_LD(LOAD(lduw, %o1 + 0x00, %g1)) + add %o1, 0x04, %o1 + add %o0, 0x04, %o0 + subcc %o2, 0x04, %o2 + bne,pn %icc, .Ltiny + EX_ST(STORE(stw, %g1, %o0 - 0x04)) + ba,a,pt %icc, .Lexit +.Lmedium_unaligned: + /* First get dest 8 byte aligned. */ + sub %g0, %o0, %g1 + and %g1, 0x7, %g1 + brz,pt %g1, 2f + sub %o2, %g1, %o2 + +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2)) + add %o1, 1, %o1 + subcc %g1, 1, %g1 + add %o0, 1, %o0 + bne,pt %icc, 1b + EX_ST(STORE(stb, %g2, %o0 - 0x01)) +2: + and %o1, 0x7, %g1 + brz,pn %g1, .Lmedium_noprefetch + sll %g1, 3, %g1 + mov 64, %g2 + sub %g2, %g1, %g2 + andn %o1, 0x7, %o1 + EX_LD(LOAD(ldx, %o1 + 0x00, %o4)) + sllx %o4, %g1, %o4 + andn %o2, 0x08 - 1, %o5 + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3)) + add %o1, 0x08, %o1 + subcc %o5, 0x08, %o5 + srlx %g3, %g2, GLOBAL_SPARE + or GLOBAL_SPARE, %o4, GLOBAL_SPARE + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00)) + add %o0, 0x08, %o0 + bne,pt %icc, 1b + sllx %g3, %g1, %o4 + srl %g1, 3, %g1 + add %o1, %g1, %o1 + brz,pn %o2, .Lexit + nop + ba,pt %icc, .Lsmall_unaligned + +.Ltiny: + EX_LD(LOAD(ldub, %o1 + 0x00, %g1)) + subcc %o2, 1, %o2 + be,pn %icc, .Lexit + EX_ST(STORE(stb, %g1, %o0 + 0x00)) + EX_LD(LOAD(ldub, %o1 + 0x01, %g1)) + subcc %o2, 1, %o2 + be,pn %icc, .Lexit + EX_ST(STORE(stb, %g1, %o0 + 0x01)) + EX_LD(LOAD(ldub, %o1 + 0x02, %g1)) + ba,pt %icc, .Lexit + EX_ST(STORE(stb, %g1, %o0 + 0x02)) + +.Lsmall: + andcc %g2, 0x3, %g0 + bne,pn %icc, .Lsmall_unaligned + andn %o2, 0x4 - 1, %o5 + sub %o2, %o5, %o2 +1: + EX_LD(LOAD(lduw, %o1 + 0x00, %g1)) + add %o1, 0x04, %o1 + subcc %o5, 0x04, %o5 + add %o0, 0x04, %o0 + bne,pt %icc, 1b + EX_ST(STORE(stw, %g1, %o0 - 0x04)) + brz,pt %o2, .Lexit + nop + ba,a,pt %icc, .Ltiny + +.Lsmall_unaligned: +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1)) + add %o1, 1, %o1 + add %o0, 1, %o0 + subcc %o2, 1, %o2 + bne,pt %icc, 1b + EX_ST(STORE(stb, %g1, %o0 - 0x01)) + ba,a,pt %icc, .Lexit +END(__memcpy_niagara4) + +#endif diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S b/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S index 20c72d9bb..50a40883c 100644 --- a/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S +++ b/libc/sysdeps/sparc/sparc64/multiarch/memcpy.S @@ -26,8 +26,19 @@ ENTRY(memcpy) # ifdef SHARED SETUP_PIC_REG_LEAF(o3, o5) # endif - andcc %o0, HWCAP_SPARC_N2, %g0 + set HWCAP_SPARC_CRYPTO, %o1 + andcc %o0, %o1, %g0 be 1f + andcc %o0, HWCAP_SPARC_N2, %g0 +# ifdef SHARED + sethi %gdop_hix22(__memcpy_niagara4), %o1 + xor %o1, %gdop_lox10(__memcpy_niagara4), %o1 +# else + set __memcpy_niagara4, %o1 +# endif + ba 10f + nop +1: be 1f andcc %o0, HWCAP_SPARC_BLKINIT, %g0 # ifdef SHARED sethi %gdop_hix22(__memcpy_niagara2), %o1 @@ -77,8 +88,19 @@ ENTRY(__mempcpy) # ifdef SHARED SETUP_PIC_REG_LEAF(o3, o5) # endif - andcc %o0, HWCAP_SPARC_N2, %g0 + set HWCAP_SPARC_CRYPTO, %o1 + andcc %o0, %o1, %g0 be 1f + andcc %o0, HWCAP_SPARC_N2, %g0 +# ifdef SHARED + sethi %gdop_hix22(__mempcpy_niagara4), %o1 + xor %o1, %gdop_lox10(__mempcpy_niagara4), %o1 +# else + set __mempcpy_niagara4, %o1 +# endif + ba 10f + nop +1: be 1f andcc %o0, HWCAP_SPARC_BLKINIT, %g0 # ifdef SHARED sethi %gdop_hix22(__mempcpy_niagara2), %o1 diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S b/libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S new file mode 100644 index 000000000..c5a2f1bef --- /dev/null +++ b/libc/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S @@ -0,0 +1,124 @@ +/* Set a block of memory to some byte value. For SUN4V Niagara-4. + Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller (davem@davemloft.net) + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 + +#if !defined NOT_IN_libc + + .register %g2, #scratch + .register %g3, #scratch + + .text + .align 32 + +ENTRY(__memset_niagara4) + andcc %o1, 0xff, %o4 + be,pt %icc, 1f + mov %o2, %o1 + sllx %o4, 8, %g1 + or %g1, %o4, %o2 + sllx %o2, 16, %g1 + or %g1, %o2, %o2 + sllx %o2, 32, %g1 + ba,pt %icc, 1f + or %g1, %o2, %o4 +END(__memset_niagara4) + + .align 32 +ENTRY(__bzero_niagara4) + clr %o4 +1: cmp %o1, 16 + ble %icc, .Ltiny + mov %o0, %o3 + sub %g0, %o0, %g1 + and %g1, 0x7, %g1 + brz,pt %g1, .Laligned8 + sub %o1, %g1, %o1 +1: stb %o4, [%o0 + 0x00] + subcc %g1, 1, %g1 + bne,pt %icc, 1b + add %o0, 1, %o0 +.Laligned8: + cmp %o1, 64 + (64 - 8) + ble .Lmedium + sub %g0, %o0, %g1 + andcc %g1, (64 - 1), %g1 + brz,pn %g1, .Laligned64 + sub %o1, %g1, %o1 +1: stx %o4, [%o0 + 0x00] + subcc %g1, 8, %g1 + bne,pt %icc, 1b + add %o0, 0x8, %o0 +.Laligned64: + andn %o1, 64 - 1, %g1 + sub %o1, %g1, %o1 + brnz,pn %o4, .Lnon_bzero_loop + mov 0x20, %g2 +1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + subcc %g1, 0x40, %g1 + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + bne,pt %icc, 1b + add %o0, 0x40, %o0 +.Lpostloop: + cmp %o1, 8 + bl,pn %icc, .Ltiny + membar #StoreStore|#StoreLoad +.Lmedium: + andn %o1, 0x7, %g1 + sub %o1, %g1, %o1 +1: stx %o4, [%o0 + 0x00] + subcc %g1, 0x8, %g1 + bne,pt %icc, 1b + add %o0, 0x08, %o0 + andcc %o1, 0x4, %g1 + be,pt %icc, .Ltiny + sub %o1, %g1, %o1 + stw %o4, [%o0 + 0x00] + add %o0, 0x4, %o0 +.Ltiny: + cmp %o1, 0 + be,pn %icc, .Lexit +1: subcc %o1, 1, %o1 + stb %o4, [%o0 + 0x00] + bne,pt %icc, 1b + add %o0, 1, %o0 +.Lexit: + retl + mov %o3, %o0 +.Lnon_bzero_loop: + mov 0x08, %g3 + mov 0x28, %o5 +1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + subcc %g1, 0x40, %g1 + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P + add %o0, 0x10, %o0 + stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P + bne,pt %icc, 1b + add %o0, 0x30, %o0 + ba,a,pt %icc, .Lpostloop +END(__bzero_niagara4) + +#endif diff --git a/libc/sysdeps/sparc/sparc64/multiarch/memset.S b/libc/sysdeps/sparc/sparc64/multiarch/memset.S index 26cc669d6..8b3faee91 100644 --- a/libc/sysdeps/sparc/sparc64/multiarch/memset.S +++ b/libc/sysdeps/sparc/sparc64/multiarch/memset.S @@ -26,8 +26,19 @@ ENTRY(memset) # ifdef SHARED SETUP_PIC_REG_LEAF(o3, o5) # endif - andcc %o0, HWCAP_SPARC_BLKINIT, %g0 - be 9f + set HWCAP_SPARC_CRYPTO, %o1 + andcc %o0, %o1, %g0 + be 1f + andcc %o0, HWCAP_SPARC_BLKINIT, %g0 +# ifdef SHARED + sethi %gdop_hix22(__memset_niagara4), %o1 + xor %o1, %gdop_lox10(__memset_niagara4), %o1 +# else + set __memset_niagara4, %o1 +# endif + ba 10f + nop +1: be 9f nop # ifdef SHARED sethi %gdop_hix22(__memset_niagara1), %o1 @@ -57,8 +68,19 @@ ENTRY(__bzero) # ifdef SHARED SETUP_PIC_REG_LEAF(o3, o5) # endif - andcc %o0, HWCAP_SPARC_BLKINIT, %g0 - be 9f + set HWCAP_SPARC_CRYPTO, %o1 + andcc %o0, %o1, %g0 + be 1f + andcc %o0, HWCAP_SPARC_BLKINIT, %g0 +# ifdef SHARED + sethi %gdop_hix22(__bzero_niagara4), %o1 + xor %o1, %gdop_lox10(__bzero_niagara4), %o1 +# else + set __bzero_niagara4, %o1 +# endif + ba 10f + nop +1: be 9f nop # ifdef SHARED sethi %gdop_hix22(__bzero_niagara1), %o1 diff --git a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h index 67d82e6e7..0714ed02b 100644 --- a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h +++ b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h @@ -51,7 +51,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __S32_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE __S32_TYPE diff --git a/libc/sysdeps/unix/bsd/confstr.h b/libc/sysdeps/unix/bsd/confstr.h deleted file mode 100644 index befefb652..000000000 --- a/libc/sysdeps/unix/bsd/confstr.h +++ /dev/null @@ -1 +0,0 @@ -#define CS_PATH "/usr/ucb:/bin:/usr/bin" diff --git a/libc/sysdeps/unix/syscalls.list b/libc/sysdeps/unix/syscalls.list index b38b03e19..46205825c 100644 --- a/libc/sysdeps/unix/syscalls.list +++ b/libc/sysdeps/unix/syscalls.list @@ -41,7 +41,7 @@ kill - kill i:ii __kill kill link - link i:ss __link link listen - listen i:ii __listen listen lseek - lseek i:iii __libc_lseek __lseek lseek -madvise - madvise i:pii madvise +madvise - madvise i:pii __madvise madvise mkdir - mkdir i:si __mkdir mkdir mmap - mmap b:aniiii __mmap mmap mprotect - mprotect i:aii __mprotect mprotect diff --git a/libc/sysdeps/gnu/_G_config.h b/libc/sysdeps/unix/sysv/linux/_G_config.h index 4d3ae36c4..ec2e33317 100644 --- a/libc/sysdeps/gnu/_G_config.h +++ b/libc/sysdeps/unix/sysv/linux/_G_config.h @@ -28,8 +28,6 @@ typedef struct __off64_t __pos; __mbstate_t __state; } _G_fpos64_t; -#define _G_off64_t __off64_t -#define _G_stat64 stat64 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T # include <gconv.h> typedef union diff --git a/libc/sysdeps/unix/sysv/linux/configure b/libc/sysdeps/unix/sysv/linux/configure index b04f7715f..76cfea1dc 100644 --- a/libc/sysdeps/unix/sysv/linux/configure +++ b/libc/sysdeps/unix/sysv/linux/configure @@ -1,102 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/unix/sysv/linux. diff --git a/libc/sysdeps/unix/sysv/linux/init-first.c b/libc/sysdeps/unix/sysv/linux/init-first.c deleted file mode 100644 index 00234e689..000000000 --- a/libc/sysdeps/unix/sysv/linux/init-first.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. Linux version. - Copyright (C) 1995-2004, 2005, 2007, 2011 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, see - <http://www.gnu.org/licenses/>. */ - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <sysdep.h> -#include <fpu_control.h> -#include <sys/param.h> -#include <sys/types.h> -#include <libc-internal.h> - -#include <ldsodefs.h> - -/* Set nonzero if we have to be prepared for more then one libc being - used in the process. Safe assumption if initializer never runs. */ -int __libc_multiple_libcs attribute_hidden = 1; - -/* Remember the command line argument and enviroment contents for - later calls of initializers for dynamic libraries. */ -int __libc_argc attribute_hidden; -char **__libc_argv attribute_hidden; - - -void -__libc_init_first (int argc, char **argv, char **envp) -{ -#ifdef SHARED - /* For DSOs we do not need __libc_init_first but instead _init. */ -} - -void -attribute_hidden -_init (int argc, char **argv, char **envp) -{ -#endif -#ifdef USE_NONOPTION_FLAGS - extern void __getopt_clean_environment (char **); -#endif - - __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; - - /* Make sure we don't initialize twice. */ - if (!__libc_multiple_libcs) - { - /* Set the FPU control word to the proper default value if the - kernel would use a different value. (In a static program we - don't have this information.) */ -#ifdef SHARED - if (__fpu_control != GLRO(dl_fpu_control)) -#endif - __setfpucw (__fpu_control); - } - - /* Save the command-line arguments. */ - __libc_argc = argc; - __libc_argv = argv; - __environ = envp; - -#ifndef SHARED - __libc_init_secure (); - - /* First the initialization which normally would be done by the - dynamic linker. */ - _dl_non_dynamic_init (); -#endif - -#ifdef VDSO_SETUP - VDSO_SETUP (); -#endif - - __init_misc (argc, argv, envp); - -#ifdef USE_NONOPTION_FLAGS - /* This is a hack to make the special getopt in GNU libc working. */ - __getopt_clean_environment (envp); -#endif - - /* Initialize ctype data. */ - __ctype_init (); - -#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS - __libc_global_ctors (); -#endif -} - -/* This function is defined here so that if this file ever gets into - ld.so we will get a link error. Having this file silently included - in ld.so causes disaster, because the _init definition above will - cause ld.so to gain an init function, which is not a cool thing. */ - -extern void _dl_start (void) __attribute__ ((noreturn)); - -void -_dl_start (void) -{ - abort (); -} diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/Makefile b/libc/sysdeps/unix/sysv/linux/powerpc/Makefile index f6dccd9a3..6bdf4dc7f 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/Makefile +++ b/libc/sysdeps/unix/sysv/linux/powerpc/Makefile @@ -16,3 +16,9 @@ endif ifeq ($(subdir),elf) sysdep_routines += dl-vdso endif + +ifeq ($(subdir),misc) +sysdep_headers += bits/ppc.h +sysdep_routines += get_clockfreq get_timebase_freq +tests += test-gettimebasefreq +endif diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h index c984e2bbb..91797b74c 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h +++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h @@ -1,5 +1,5 @@ /* O_*, F_*, FD_* bit values for Linux/PowerPC. - Copyright (C) 1995-1998, 2000, 2003, 2004, 2006, 2007, 2009, 2010, 2011 + Copyright (C) 1995-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -232,6 +232,19 @@ struct f_owner_ex we splice from/to). */ # define SPLICE_F_MORE 4 /* Expect more data. */ # define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */ + + +/* File handle structure. */ +struct file_handle +{ + unsigned int handle_bytes; + int handle_type; + /* File identifier. */ + unsigned char f_handle[0]; +}; + +/* Maximum handle size (for now). */ +# define MAX_HANDLE_SZ 128 #endif __BEGIN_DECLS @@ -278,6 +291,19 @@ extern int fallocate64 (int __fd, int __mode, __off64_t __offset, __off64_t __len); # endif + +/* Map file name to file handle. */ +extern int name_to_handle_at (int __dfd, const char *__name, + struct file_handle *__handle, int *__mnt_id, + int __flags) __THROW; + +/* Open file using the file handle. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int open_by_handle_at (int __mountdirfd, struct file_handle *__handle, + int __flags); + #endif __END_DECLS diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h new file mode 100644 index 000000000..76542d9d8 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ppc.h @@ -0,0 +1,33 @@ +/* Facilities specific to the PowerPC architecture on Linux + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_PPC_H +#define _BITS_PPC_H + +#ifndef _SYS_PLATFORM_PPC_H +# error "Never include this file directly; use <sys/platform/ppc.h> instead." +#endif + +__BEGIN_DECLS + +/* Read the time base frequency. */ +extern uint64_t __ppc_get_timebase_freq (void); + +__END_DECLS + +#endif diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/configure b/libc/sysdeps/unix/sysv/linux/powerpc/configure index 802b37160..7df7e481f 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/configure +++ b/libc/sysdeps/unix/sysv/linux/powerpc/configure @@ -1,123 +1,3 @@ - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/unix/sysv/linux/powerpc/. diff --git a/libc/sysdeps/mach/hurd/dl-cache.c b/libc/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c index 5c01c3d6d..5559dd5c0 100644 --- a/libc/sysdeps/mach/hurd/dl-cache.c +++ b/libc/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c @@ -1,5 +1,5 @@ -/* Stubby version of dl-cache; the Hurd doesn't support this "feature". - Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Get the frequency of the time base. + Copyright (C) 2012 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 @@ -16,13 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -const char * -_dl_load_cache_lookup (const char *name) -{ - return 0; -} +#include <stdint.h> +#include <libc-internal.h> -void -_dl_unload_cache (void) +uint64_t +__get_timebase_freq (void) { + return (uint64_t) __get_clockfreq (); } +weak_alias (__get_timebase_freq, __ppc_get_timebase_freq) diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c b/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c index 57b36afc4..ba7ae294b 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c +++ b/libc/sysdeps/unix/sysv/linux/powerpc/init-first.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2007 Free Software Foundation, Inc. +/* Initialization code run first thing by the ELF startup code. Linux/PowerPC. + Copyright (C) 2007-2012 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 @@ -45,4 +46,4 @@ _libc_vdso_platform_setup (void) # define VDSO_SETUP _libc_vdso_platform_setup #endif -#include "../init-first.c" +#include <csu/init-first.c> diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions index 6fa0119e9..8d1c3a59d 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions +++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions @@ -30,4 +30,7 @@ libc { GLIBC_2.11 { fallocate64; } + GLIBC_2.17 { + __ppc_get_timebase_freq; + } } diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist index 75123b9f3..ab96361d4 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist +++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist @@ -1775,6 +1775,7 @@ GLIBC_2.16 GLIBC_2.17 GLIBC_2.17 A secure_getenv F + __ppc_get_timebase_freq F GLIBC_2.2 GLIBC_2.2 A _IO_adjust_wcolumn F diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions index 8334741ae..3ff01d1c1 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions +++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions @@ -19,4 +19,7 @@ libc { setcontext; swapcontext; } + GLIBC_2.17 { + __ppc_get_timebase_freq; + } } diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist index e2484d3f2..a60b72ad1 100644 --- a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist +++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist @@ -81,6 +81,7 @@ GLIBC_2.16 GLIBC_2.17 GLIBC_2.17 A secure_getenv F + __ppc_get_timebase_freq F GLIBC_2.3 GLIBC_2.3 A _Exit F diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c b/libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c new file mode 100644 index 000000000..a3f3bd6f5 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/powerpc/test-gettimebasefreq.c @@ -0,0 +1,62 @@ +/* Check __ppc_get_timebase_freq() for architecture changes + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +/* Test if __ppc_get_timebase_freq() works and is different from zero. A read + failure might indicate a Linux Kernel change. + This test also use the frequency to compute the real elapsed time. */ + +#include <inttypes.h> +#include <stdio.h> + +#include <sys/platform/ppc.h> + +/* Maximum value of the Time Base Register: 2^60 - 1. */ +#define MAX_TB 0xFFFFFFFFFFFFFFF + +static int +do_test (void) +{ + uint64_t t1, t2, f, diff; + + t1 = __ppc_get_timebase (); + printf ("t1 = %"PRIu64"\n", t1); + + f = __ppc_get_timebase_freq (); + printf ("Time Base frequency = %"PRIu64" Hz\n", f); + + if (f == 0) { + printf ("Fail: The time base frequency can't be zero."); + return 1; + } + + t2 = __ppc_get_timebase (); + printf ("t2 = %"PRIu64"\n", t2); + + if (t2 > t1) { + diff = t2 - t1; + } else { + diff = (MAX_TB - t2) + t1; + } + + printf ("Elapsed time = %1.2f usecs\n", (double) diff * 1000000 / f ); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h index b63048840..ee7e22b63 100644 --- a/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h +++ b/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h @@ -51,7 +51,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SLONGWORD_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE void * diff --git a/libc/sysdeps/unix/sysv/linux/s390/init-first.c b/libc/sysdeps/unix/sysv/linux/s390/init-first.c index c97138270..a066daefd 100644 --- a/libc/sysdeps/unix/sysv/linux/s390/init-first.c +++ b/libc/sysdeps/unix/sysv/linux/s390/init-first.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2008 Free Software Foundation, Inc. +/* Initialization code run first thing by the ELF startup code. Linux/s390. + Copyright (C) 2008-2012 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 @@ -46,4 +47,4 @@ _libc_vdso_platform_setup (void) # define VDSO_SETUP _libc_vdso_platform_setup #endif -#include "../init-first.c" +#include <csu/init-first.c> diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h index e55d642e7..8be55a8d7 100644 --- a/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h +++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h @@ -51,7 +51,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __S32_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SLONGWORD_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE void * diff --git a/libc/sysdeps/unix/sysv/linux/syscalls.list b/libc/sysdeps/unix/sysv/linux/syscalls.list index 63432725d..2e6cf9c60 100644 --- a/libc/sysdeps/unix/sysv/linux/syscalls.list +++ b/libc/sysdeps/unix/sysv/linux/syscalls.list @@ -36,11 +36,9 @@ ioperm - ioperm i:iii ioperm iopl - iopl i:i iopl klogctl EXTRA syslog i:isi klogctl lchown - lchown i:sii __lchown lchown -madvise - madvise i:pii madvise mincore - mincore i:anV mincore mlock - mlock i:bn mlock mlockall - mlockall i:i mlockall -mmap - mmap b:aniiii __mmap mmap mount EXTRA mount i:sssip __mount mount mremap EXTRA mremap b:ainip __mremap mremap munlock - munlock i:ai munlock diff --git a/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h index 397e86724..ebb5bbb64 100644 --- a/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h +++ b/libc/sysdeps/unix/sysv/linux/x86/bits/typesizes.h @@ -65,7 +65,6 @@ #define __USECONDS_T_TYPE __U32_TYPE #define __SUSECONDS_T_TYPE __SYSCALL_SLONG_TYPE #define __DADDR_T_TYPE __S32_TYPE -#define __SWBLK_T_TYPE __SYSCALL_SLONG_TYPE #define __KEY_T_TYPE __S32_TYPE #define __CLOCKID_T_TYPE __S32_TYPE #define __TIMER_T_TYPE void * diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c b/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c index e8b52eacb..dd41f0f7a 100644 --- a/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c +++ b/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2007, 2011 Free Software Foundation, Inc. +/* Initialization code run first thing by the ELF startup code. Linux/x86-64. + Copyright (C) 2007-2012 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 @@ -54,4 +55,4 @@ _libc_vdso_platform_setup (void) # define VDSO_SETUP _libc_vdso_platform_setup #endif -#include "../init-first.c" +#include <csu/init-first.c> diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c b/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c index c2aea9d4e..5fe472ea2 100644 --- a/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c +++ b/libc/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2012 Free Software Foundation, Inc. +/* Initialization code run first thing by the ELF startup code. Linux/x32. + Copyright (C) 2012 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 @@ -37,4 +38,4 @@ _libc_vdso_platform_setup (void) # define VDSO_SETUP _libc_vdso_platform_setup #endif -#include "../../init-first.c" +#include <csu/init-first.c> diff --git a/libc/sysdeps/x86_64/configure b/libc/sysdeps/x86_64/configure index adbaeee32..0fa0e1ecf 100644 --- a/libc/sysdeps/x86_64/configure +++ b/libc/sysdeps/x86_64/configure @@ -1,128 +1,4 @@ -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in diff --git a/libc/sysdeps/x86_64/dl-tlsdesc.h b/libc/sysdeps/x86_64/dl-tlsdesc.h index 06ede0214..ec750904f 100644 --- a/libc/sysdeps/x86_64/dl-tlsdesc.h +++ b/libc/sysdeps/x86_64/dl-tlsdesc.h @@ -20,12 +20,6 @@ #ifndef _X86_64_DL_TLSDESC_H # define _X86_64_DL_TLSDESC_H 1 -/* Use this to access DT_TLSDESC_PLT and DT_TLSDESC_GOT. */ -#ifndef ADDRIDX -# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag)) -#endif - /* Type used to represent a TLS descriptor in the GOT. */ struct tlsdesc { diff --git a/libc/sysdeps/x86_64/fpu/libm-test-ulps b/libc/sysdeps/x86_64/fpu/libm-test-ulps index b02b9e6ba..9c5157ff7 100644 --- a/libc/sysdeps/x86_64/fpu/libm-test-ulps +++ b/libc/sysdeps/x86_64/fpu/libm-test-ulps @@ -812,6 +812,12 @@ float: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "Real part of: clog (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -5.421010862427522170184200798202494495630e-20 + 3.548665303440282824232502561095699343814e-4516 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i": +float: 1 +ifloat: 1 Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i": float: 1 ifloat: 1 @@ -841,6 +847,9 @@ ldouble: 1 Test "Real part of: clog (0x1.fp+16383 - 0x1p-16445 i) == 11356.49165759582936919077408168801636572 - 0 i": ildouble: 1 ldouble: 1 +Test "Imaginary part of: clog (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 5.0844550531823026520677817684239496041087e-32 + 1.2627468605458094918919206628466016525397 i": +ildouble: 1 +ldouble: 1 Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i": double: 1 idouble: 1 @@ -868,6 +877,12 @@ ldouble: 1 Test "Real part of: clog (0x1p-16445 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i": ildouble: 1 ldouble: 1 +Test "Imaginary part of: clog (0x2818p-15 + 0x798fp-15 i) == 1.5366822245016167178749091974664853785194e-08 + 1.2522014929038946066987318471922169174157 i": +float: 1 +ifloat: 1 +Test "Real part of: clog (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 4.4469229730850767799109418892826021157328e-20 + 1.2046235979300843056806465045930070146351 i": +ildouble: 1 +ldouble: 1 Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i": float: 1 ifloat: 1 @@ -1009,6 +1024,21 @@ idouble: 1 ifloat: 1 ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -2.354315103889861110220423157644627849164e-20 + 1.541165759405643564697852372112893034397e-4516 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "Real part of: clog10 (0x1.000566p0 + 0x1.234p-10 i) == 3.604093470239754109961125085078190708674e-5 + 4.824745078422174667425851670822596859720e-4 i": float: 1 ifloat: 1 @@ -1068,6 +1098,29 @@ ldouble: 1 Test "Real part of: clog10 (0x1.fp+16383 - 0x1p-16445 i) == 4932.061660674182269085496060792589701158 - 0 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x11682p-23 + 0x7ffed1p-23 i) == 5.0916490233953865181284669870035717560498e-13 + 0.6784968969384861816694467029319146542069 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i": +double: 1 +idouble: 1 Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i": double: 1 idouble: 1 @@ -1151,6 +1204,75 @@ ifloat: 1 Test "Real part of: clog10 (0x1p-8190 + 1.0 i) == 2.920285685286322365786846845062520925172e-4932 + 6.821881769209206737428918127156778851051e-1 i": ildouble: 1 ldouble: 1 +Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x659b70ab7971bp-53 + 0x1f5d111e08abecp-53 i) == -1.0893543813872082317104059174982092534059e-30 + 0.5954257879188711495921161433751775633232 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x81b7efa81fc35ad1p-65 + 0x1ef4b835f1c79d812p-65 i) == -4.3074341162203896332989394770760901408798e-39 + 0.5709443672155660428417571212549720987784 i": +ildouble: 1 +ldouble: 1 +Test "Real part of: clog10 (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -4.2289432987513243393180377141513840878196e-30 + 0.4252020027092323591068799049905597805296 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i": +double: 1 +idouble: 1 +Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i": +double: 1 +idouble: 1 Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i": double: 1 idouble: 1 @@ -1611,9 +1733,14 @@ ldouble: 1 Test "Imaginary part of: ctan (0x1p1023 + 1 i) == -0.2254627924997545057926782581695274244229 + 0.8786063118883068695462540226219865087189 i": ildouble: 1 ldouble: 1 +Test "Real part of: ctan (0x1p127 + 1 i) == 0.2446359391192790896381501310437708987204 + 0.9101334047676183761532873794426475906201 i": +float: 1 +ifloat: 1 Test "Imaginary part of: ctan (0x1p127 + 1 i) == 0.2446359391192790896381501310437708987204 + 0.9101334047676183761532873794426475906201 i": double: 1 +float: 2 idouble: 1 +ifloat: 2 Test "Real part of: ctan (0x3.243f6cp-1 + 0 i) == -2.287733242885645987394874673945769518150e7 + 0.0 i": float: 1 ifloat: 1 @@ -1758,7 +1885,12 @@ ildouble: 1 ldouble: 1 Test "Real part of: ctanh (1 + 0x1p127 i) == 0.9101334047676183761532873794426475906201 + 0.2446359391192790896381501310437708987204 i": double: 1 +float: 2 idouble: 1 +ifloat: 2 +Test "Imaginary part of: ctanh (1 + 0x1p127 i) == 0.9101334047676183761532873794426475906201 + 0.2446359391192790896381501310437708987204 i": +float: 1 +ifloat: 1 Test "Imaginary part of: ctanh (45 + 1 i) == 1.000000000000000000000000000000000000001 + 1.490158918874345552942703234806348520895e-39 i": ildouble: 1 ldouble: 1 @@ -2399,8 +2531,8 @@ ifloat: 2 ildouble: 1 ldouble: 1 Test "sin_upward (3) == 0.1411200080598672221007448028081102798469": -float: 1 -ifloat: 1 +float: 2 +ifloat: 2 ildouble: 1 ldouble: 1 Test "sin_upward (4) == -0.7568024953079282513726390945118290941359": @@ -2430,12 +2562,6 @@ ifloat: 1 Test "sincos (0.80190127184058835, &sin_res, &cos_res) puts 0.69534156199418473 in cos_res": double: 1 idouble: 1 -Test "sincos (0x1p+120, &sin_res, &cos_res) puts -9.25879022854837867303861764107414946730833e-01 in cos_res": -float: 1 -ifloat: 1 -Test "sincos (0x1p+127, &sin_res, &cos_res) puts 7.81914638714960072263910298466369236613162e-01 in cos_res": -float: 1 -ifloat: 1 Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res": double: 1 float: 1 @@ -2706,7 +2832,9 @@ ildouble: 2 ldouble: 2 Test "y1 (0x1.27e204p+99) == -8.881610148467797208469612080785210013461e-16": double: 1 +float: 1 idouble: 1 +ifloat: 1 ildouble: 1 ldouble: 1 Test "y1 (1.5) == -0.412308626973911295952829820633445323": @@ -3041,20 +3169,22 @@ ldouble: 1 Function: Imaginary part of "clog": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Function: Real part of "clog10": double: 2 -float: 1 +float: 2 idouble: 2 -ifloat: 1 +ifloat: 2 ildouble: 1 ldouble: 1 Function: Imaginary part of "clog10": double: 1 -float: 5 +float: 1 idouble: 1 -ifloat: 5 +ifloat: 1 ildouble: 1 ldouble: 1 @@ -3085,8 +3215,8 @@ ildouble: 1 ldouble: 1 Function: "cos_upward": -float: 1 -ifloat: 1 +float: 2 +ifloat: 2 ildouble: 1 ldouble: 1 @@ -3174,17 +3304,17 @@ ldouble: 1 Function: Real part of "ctan": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 2 ldouble: 2 Function: Imaginary part of "ctan": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 1 ldouble: 1 @@ -3242,9 +3372,9 @@ ldouble: 4 Function: Real part of "ctanh": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 ildouble: 1 ldouble: 1 @@ -3445,8 +3575,8 @@ ildouble: 1 ldouble: 1 Function: "sin_upward": -float: 1 -ifloat: 1 +float: 2 +ifloat: 2 ildouble: 1 ldouble: 1 diff --git a/libc/sysdeps/x86_64/fpu/s_sincosf.S b/libc/sysdeps/x86_64/fpu/s_sincosf.S new file mode 100644 index 000000000..3334a3a78 --- /dev/null +++ b/libc/sysdeps/x86_64/fpu/s_sincosf.S @@ -0,0 +1,558 @@ +/* Optimized sincosf function. + Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#define __need_Emath +#include <bits/errno.h> + +/* Short algorithm description: + * + * 1) if |x|==0: sin(x)=x, + * cos(x)=1. + * 2) if |x|<2^-27: sin(x)=x-x*DP_SMALL, raising underflow only when needed, + * cos(x)=1-|x|. + * 3) if |x|<2^-5 : sin(x)=x+x*x^2*DP_SIN2_0+x^5*DP_SIN2_1, + * cos(x)=1+1*x^2*DP_COS2_0+x^5*DP_COS2_1 + * 4) if |x|< Pi/4: sin(x)=x+x*x^2*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))), + * cos(x)=1+1*x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). + * 5) if |x| < 9*Pi/4: + * 5.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0x0e, n=k+1, t=|x|-j*Pi/4. + * 5.2) Reconstruction: + * sign_sin = sign(x) * (-1.0)^(( n >>2)&1) + * sign_cos = (-1.0)^(((n+2)>>2)&1) + * poly_sin = ((((S4*t^2 + S3)*t^2 + S2)*t^2 + S1)*t^2 + S0)*t^2*t+t + * poly_cos = ((((C4*t^2 + C3)*t^2 + C2)*t^2 + C1)*t^2 + C0)*t^2*s+s + * if(n&2 != 0) { + * using cos(t) and sin(t) polynomials for |t|<Pi/4, results are + * cos(x) = poly_sin * sign_cos + * sin(x) = poly_cos * sign_sin + * } else { + * sin(x) = poly_sin * sign_sin + * cos(x) = poly_cos * sign_cos + * } + * 6) if |x| < 2^23, large args: + * 6.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4 + * 6.2) Reconstruction same as (5.2). + * 7) if |x| >= 2^23, very large args: + * 7.1) Range reduction: + * k=trunc(|x|/(Pi/4)), j=(k+1)&0xfffffffe, n=k+1, t=|x|-j*Pi/4. + * 7.2) Reconstruction same as (5.2). + * 8) if x is Inf, return x-x, and set errno=EDOM. + * 9) if x is NaN, return x-x. + * + * Special cases: + * sin/cos(+-0) = +-0/1 not raising inexact/underflow, + * sin/cos(subnormal) raises inexact/underflow, + * sin/cos(min_normalized) raises inexact/underflow, + * sin/cos(normalized) raises inexact, + * sin/cos(Inf) = NaN, raises invalid, sets errno to EDOM, + * sin/cos(NaN) = NaN. + */ + +# define ARG_SIN_PTR %rdi +# define ARG_COS_PTR %rsi + + .text +ENTRY(__sincosf) + /* Input: %xmm0 contains single precision argument x */ + /* %rdi points to sin result */ + /* %rsi points to cos result */ + + movd %xmm0, %eax /* Bits of x */ + movaps %xmm0, %xmm7 /* Copy of x */ + cvtss2sd %xmm0, %xmm0 /* DP x */ + movss L(SP_ABS_MASK)(%rip), %xmm3 + movl %eax, %r8d /* Copy of x bits */ + andl $0x7fffffff, %eax /* |x| */ + + cmpl $0x3f490fdb, %eax /* |x|<Pi/4 ? */ + jb L(arg_less_pio4) + + /* Here if |x|>=Pi/4 */ + andps %xmm7, %xmm3 /* SP |x| */ + andpd L(DP_ABS_MASK)(%rip),%xmm0 /* DP |x| */ + movss L(SP_INVPIO4)(%rip), %xmm2 /* SP 1/(Pi/4) */ + + cmpl $0x40e231d6, %eax /* |x|<9*Pi/4 ? */ + jae L(large_args) + + /* Here if Pi/4<=|x|<9*Pi/4 */ + mulss %xmm3, %xmm2 /* SP |x|/(Pi/4) */ + movl %r8d, %ecx /* Load x */ + cvttss2si %xmm2, %eax /* k, number of Pi/4 in x */ + lea L(PIO4J)(%rip), %r9 + shrl $29, %ecx /* (sign of x) << 2 */ + addl $1, %eax /* k+1 */ + movl $0x0e, %edx + andl %eax, %edx /* j = (k+1)&0x0e */ + subsd (%r9,%rdx,8), %xmm0 /* t = |x| - j * Pi/4 */ + +L(reconstruction): + /* Input: %eax=n, %xmm0=t, %ecx=sign(x) */ + + movaps %xmm0, %xmm4 /* t */ + movhpd L(DP_ONES)(%rip), %xmm4 /* 1|t */ + mulsd %xmm0, %xmm0 /* y=t^2 */ + movl $2, %edx + unpcklpd %xmm0, %xmm0 /* y|y */ + addl %eax, %edx /* k+2 */ + movaps %xmm0, %xmm1 /* y|y */ + mulpd %xmm0, %xmm0 /* z=t^4|z=t^4 */ + + movaps L(DP_SC4)(%rip), %xmm2 /* S4 */ + mulpd %xmm0, %xmm2 /* z*S4 */ + movaps L(DP_SC3)(%rip), %xmm3 /* S3 */ + mulpd %xmm0, %xmm3 /* z*S3 */ + xorl %eax, %ecx /* (sign_x ^ (k>>2))<<2 */ + addpd L(DP_SC2)(%rip), %xmm2 /* S2+z*S4 */ + mulpd %xmm0, %xmm2 /* z*(S2+z*S4) */ + shrl $2, %edx /* (k+2)>>2 */ + addpd L(DP_SC1)(%rip), %xmm3 /* S1+z*S3 */ + mulpd %xmm0, %xmm3 /* z*(S1+z*S3) */ + shrl $2, %ecx /* sign_x ^ k>>2 */ + addpd L(DP_SC0)(%rip), %xmm2 /* S0+z*(S2+z*S4) */ + andl $1, %edx /* sign_cos = ((k+2)>>2)&1 */ + mulpd %xmm1, %xmm2 /* y*(S0+z*(S2+z*S4)) */ + andl $1, %ecx /* sign_sin = sign_x ^ ((k>>2)&1) */ + addpd %xmm2, %xmm3 /* y*(S0+y*(S1+y*(S2+y*(S3+y*S4)))) */ + lea L(DP_ONES)(%rip), %r9 + mulpd %xmm4, %xmm3 /*t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/ + testl $2, %eax /* n&2 != 0 ? */ + addpd %xmm4, %xmm3 /*t+t*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/ + jnz L(sin_result_sin_poly) + +/*L(sin_result_cos_poly):*/ + /* + * Here if + * cos(x) = poly_sin * sign_cos + * sin(x) = poly_cos * sign_sin + */ + movsd (%r9,%rcx,8), %xmm4 /* 0|sign_sin */ + movhpd (%r9,%rdx,8), %xmm4 /* sign_cos|sign_sin */ + mulpd %xmm4, %xmm3 /* result_cos|result_sin */ + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movss %xmm0, (ARG_SIN_PTR) /* store sin(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */ + movss %xmm0, (ARG_COS_PTR) /* store cos(x) */ + ret + + .p2align 4 +L(sin_result_sin_poly): + /* + * Here if + * sin(x) = poly_sin * sign_sin + * cos(x) = poly_cos * sign_cos + */ + movsd (%r9,%rdx,8), %xmm4 /* 0|sign_cos */ + movhpd (%r9,%rcx,8), %xmm4 /* sign_sin|sign_cos */ + mulpd %xmm4, %xmm3 /* result_sin|result_cos */ + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movss %xmm0, (ARG_COS_PTR) /* store cos(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move sin(x) to xmm0[0] */ + movss %xmm0, (ARG_SIN_PTR) /* store sin(x) */ + ret + + .p2align 4 +L(large_args): + /* Here if |x|>=9*Pi/4 */ + cmpl $0x7f800000, %eax /* x is Inf or NaN ? */ + jae L(arg_inf_or_nan) + + /* Here if finite |x|>=9*Pi/4 */ + cmpl $0x4b000000, %eax /* |x|<2^23 ? */ + jae L(very_large_args) + + /* Here if 9*Pi/4<=|x|<2^23 */ + movsd L(DP_INVPIO4)(%rip), %xmm1 /* 1/(Pi/4) */ + mulsd %xmm0, %xmm1 /* |x|/(Pi/4) */ + cvttsd2si %xmm1, %eax /* k=trunc(|x|/(Pi/4)) */ + addl $1, %eax /* k+1 */ + movl %eax, %edx + andl $0xfffffffe, %edx /* j=(k+1)&0xfffffffe */ + cvtsi2sdl %edx, %xmm4 /* DP j */ + movl %r8d, %ecx /* Load x */ + movsd L(DP_PIO4HI)(%rip), %xmm2 /* -PIO4HI = high part of -Pi/4 */ + shrl $29, %ecx /* (sign of x) << 2 */ + mulsd %xmm4, %xmm2 /* -j*PIO4HI */ + movsd L(DP_PIO4LO)(%rip), %xmm3 /* -PIO4LO = low part of -Pi/4 */ + addsd %xmm2, %xmm0 /* |x| - j*PIO4HI */ + mulsd %xmm3, %xmm4 /* j*PIO4LO */ + addsd %xmm4, %xmm0 /* t = |x| - j*PIO4HI - j*PIO4LO */ + jmp L(reconstruction) + + .p2align 4 +L(very_large_args): + /* Here if finite |x|>=2^23 */ + + /* bitpos = (ix>>23) - BIAS_32 + 59; */ + shrl $23, %eax /* eb = biased exponent of x */ + subl $68, %eax /* bitpos=eb-0x7f+59, where 0x7f */ + /*is exponent bias */ + movl $28, %ecx /* %cl=28 */ + movl %eax, %edx /* bitpos copy */ + + /* j = bitpos/28; */ + div %cl /* j in register %al=%ax/%cl */ + movapd %xmm0, %xmm3 /* |x| */ + andl $0xff, %eax /* clear unneeded remainder from %ah*/ + + imull $28, %eax, %ecx /* j*28 */ + lea L(_FPI)(%rip), %r9 + movsd L(DP_HI_MASK)(%rip), %xmm4 /* DP_HI_MASK */ + movapd %xmm0, %xmm5 /* |x| */ + mulsd -16(%r9,%rax,8), %xmm3 /* tmp3 = FPI[j-2]*|x| */ + movapd %xmm0, %xmm1 /* |x| */ + mulsd -8(%r9,%rax,8), %xmm5 /* tmp2 = FPI[j-1]*|x| */ + mulsd (%r9,%rax,8), %xmm0 /* tmp0 = FPI[j]*|x| */ + addl $19, %ecx /* j*28+19 */ + mulsd 8(%r9,%rax,8), %xmm1 /* tmp1 = FPI[j+1]*|x| */ + cmpl %ecx, %edx /* bitpos>=j*28+19 ? */ + jl L(very_large_skip1) + + /* Here if bitpos>=j*28+19 */ + andpd %xmm3, %xmm4 /* HI(tmp3) */ + subsd %xmm4, %xmm3 /* tmp3 = tmp3 - HI(tmp3) */ +L(very_large_skip1): + + movsd L(DP_2POW52)(%rip), %xmm6 + movapd %xmm5, %xmm2 /* tmp2 copy */ + addsd %xmm3, %xmm5 /* tmp5 = tmp3 + tmp2 */ + movl $1, %edx + addsd %xmm5, %xmm6 /* tmp6 = tmp5 + 2^52 */ + movsd 8+L(DP_2POW52)(%rip), %xmm4 + movd %xmm6, %eax /* k = I64_LO(tmp6); */ + addsd %xmm6, %xmm4 /* tmp4 = tmp6 - 2^52 */ + movl %r8d, %ecx /* Load x */ + comisd %xmm5, %xmm4 /* tmp4 > tmp5 ? */ + jbe L(very_large_skip2) + + /* Here if tmp4 > tmp5 */ + subl $1, %eax /* k-- */ + addsd 8+L(DP_ONES)(%rip), %xmm4 /* tmp4 -= 1.0 */ +L(very_large_skip2): + + andl %eax, %edx /* k&1 */ + lea L(DP_ZERONE)(%rip), %r9 + subsd %xmm4, %xmm3 /* tmp3 -= tmp4 */ + addsd (%r9,%rdx,8), %xmm3 /* t = DP_ZERONE[k&1] + tmp3 */ + addsd %xmm2, %xmm3 /* t += tmp2 */ + shrl $29, %ecx /* (sign of x) << 2 */ + addsd %xmm3, %xmm0 /* t += tmp0 */ + addl $1, %eax /* n=k+1 */ + addsd %xmm1, %xmm0 /* t += tmp1 */ + mulsd L(DP_PIO4)(%rip), %xmm0 /* t *= PI04 */ + + jmp L(reconstruction) /* end of very_large_args peth */ + + .p2align 4 +L(arg_less_pio4): + /* Here if |x|<Pi/4 */ + cmpl $0x3d000000, %eax /* |x|<2^-5 ? */ + jl L(arg_less_2pn5) + + /* Here if 2^-5<=|x|<Pi/4 */ + movaps %xmm0, %xmm3 /* DP x */ + movhpd L(DP_ONES)(%rip), %xmm3 /* DP 1|x */ + mulsd %xmm0, %xmm0 /* DP y=x^2 */ + unpcklpd %xmm0, %xmm0 /* DP y|y */ + movaps %xmm0, %xmm1 /* y|y */ + mulpd %xmm0, %xmm0 /* z=x^4|z=x^4 */ + + movapd L(DP_SC4)(%rip), %xmm4 /* S4 */ + mulpd %xmm0, %xmm4 /* z*S4 */ + movapd L(DP_SC3)(%rip), %xmm5 /* S3 */ + mulpd %xmm0, %xmm5 /* z*S3 */ + addpd L(DP_SC2)(%rip), %xmm4 /* S2+z*S4 */ + mulpd %xmm0, %xmm4 /* z*(S2+z*S4) */ + addpd L(DP_SC1)(%rip), %xmm5 /* S1+z*S3 */ + mulpd %xmm0, %xmm5 /* z*(S1+z*S3) */ + addpd L(DP_SC0)(%rip), %xmm4 /* S0+z*(S2+z*S4) */ + mulpd %xmm1, %xmm4 /* y*(S0+z*(S2+z*S4)) */ + mulpd %xmm3, %xmm5 /* x*z*(S1+z*S3) */ + mulpd %xmm3, %xmm4 /* x*y*(S0+z*(S2+z*S4)) */ + addpd %xmm5, %xmm4 /*x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))))*/ + addpd %xmm4, %xmm3 /*x+x*y*(S0+y*(S1+y*(S2+y*(S3+y*S4))*/ + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movss %xmm0, (ARG_SIN_PTR) /* store sin(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */ + movss %xmm0, (ARG_COS_PTR) /* store cos(x) */ + ret + + .p2align 4 +L(arg_less_2pn5): + /* Here if |x|<2^-5 */ + cmpl $0x32000000, %eax /* |x|<2^-27 ? */ + jl L(arg_less_2pn27) + + /* Here if 2^-27<=|x|<2^-5 */ + movaps %xmm0, %xmm1 /* DP x */ + movhpd L(DP_ONES)(%rip), %xmm1 /* DP 1|x */ + mulsd %xmm0, %xmm0 /* DP x^2 */ + unpcklpd %xmm0, %xmm0 /* DP x^2|x^2 */ + + movaps L(DP_SINCOS2_1)(%rip), %xmm3 /* DP DP_SIN2_1 */ + mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_1 */ + addpd L(DP_SINCOS2_0)(%rip), %xmm3 /* DP DP_SIN2_0+x^2*DP_SIN2_1 */ + mulpd %xmm0, %xmm3 /* DP x^2*DP_SIN2_0+x^4*DP_SIN2_1 */ + mulpd %xmm1, %xmm3 /* DP x^3*DP_SIN2_0+x^5*DP_SIN2_1 */ + addpd %xmm1, %xmm3 /* DP x+x^3*DP_SIN2_0+x^5*DP_SIN2_1 */ + cvtpd2ps %xmm3, %xmm0 /* SP results */ + movss %xmm0, (ARG_SIN_PTR) /* store sin(x) from xmm0[0] */ + shufps $1, %xmm0, %xmm0 /* move cos(x) to xmm0[0] */ + movss %xmm0, (ARG_COS_PTR) /* store cos(x) */ + ret + + .p2align 4 +L(arg_less_2pn27): + cmpl $0, %eax /* x=0 ? */ + je L(arg_zero) /* in case x=0 return sin(+-0)==+-0 */ + /* Here if |x|<2^-27 */ + /* + * Special cases here: + * sin(subnormal) raises inexact/underflow + * sin(min_normalized) raises inexact/underflow + * sin(normalized) raises inexact + * cos(here)=1-|x| (raising inexact) + */ + movaps %xmm0, %xmm3 /* DP x */ + mulsd L(DP_SMALL)(%rip), %xmm0/* DP x*DP_SMALL */ + subsd %xmm0, %xmm3 /* DP sin result is x-x*DP_SMALL */ + andps L(SP_ABS_MASK)(%rip), %xmm7/* SP |x| */ + cvtsd2ss %xmm3, %xmm0 /* sin(x) */ + movss L(SP_ONE)(%rip), %xmm1 /* SP 1.0 */ + movss %xmm0, (ARG_SIN_PTR) /* sin(x) store */ + subss %xmm7, %xmm1 /* cos(x) */ + movss %xmm1, (ARG_COS_PTR) /* cos(x) store */ + ret + + .p2align 4 +L(arg_zero): + movss L(SP_ONE)(%rip), %xmm0 /* 1.0 */ + movss %xmm7, (ARG_SIN_PTR) /* sin(+-0)==x */ + movss %xmm0, (ARG_COS_PTR) /* cos(+-0)==1 */ + ret + + .p2align 4 +L(arg_inf_or_nan): + /* Here if |x| is Inf or NAN */ + jne L(skip_errno_setting) /* in case of x is NaN */ + + /* Here if x is Inf. Set errno to EDOM. */ + call JUMPTARGET(__errno_location) + movl $EDOM, (%rax) + + .p2align 4 +L(skip_errno_setting): + /* Here if |x| is Inf or NAN. Continued. */ + subss %xmm7, %xmm7 /* x-x, result is NaN */ + movss %xmm7, (ARG_SIN_PTR) + movss %xmm7, (ARG_COS_PTR) + ret +END(__sincosf) + + .section .rodata, "a" + .p2align 3 +L(PIO4J): /* Table of j*Pi/4, for j=0,1,..,10 */ + .long 0x00000000,0x00000000 + .long 0x54442d18,0x3fe921fb + .long 0x54442d18,0x3ff921fb + .long 0x7f3321d2,0x4002d97c + .long 0x54442d18,0x400921fb + .long 0x2955385e,0x400f6a7a + .long 0x7f3321d2,0x4012d97c + .long 0xe9bba775,0x4015fdbb + .long 0x54442d18,0x401921fb + .long 0xbeccb2bb,0x401c463a + .long 0x2955385e,0x401f6a7a + .type L(PIO4J), @object + ASM_SIZE_DIRECTIVE(L(PIO4J)) + + .p2align 3 +L(_FPI): /* 4/Pi broken into sum of positive DP values */ + .long 0x00000000,0x00000000 + .long 0x6c000000,0x3ff45f30 + .long 0x2a000000,0x3e3c9c88 + .long 0xa8000000,0x3c54fe13 + .long 0xd0000000,0x3aaf47d4 + .long 0x6c000000,0x38fbb81b + .long 0xe0000000,0x3714acc9 + .long 0x7c000000,0x3560e410 + .long 0x56000000,0x33bca2c7 + .long 0xac000000,0x31fbd778 + .long 0xe0000000,0x300b7246 + .long 0xe8000000,0x2e5d2126 + .long 0x48000000,0x2c970032 + .long 0xe8000000,0x2ad77504 + .long 0xe0000000,0x290921cf + .long 0xb0000000,0x274deb1c + .long 0xe0000000,0x25829a73 + .long 0xbe000000,0x23fd1046 + .long 0x10000000,0x2224baed + .long 0x8e000000,0x20709d33 + .long 0x80000000,0x1e535a2f + .long 0x64000000,0x1cef904e + .long 0x30000000,0x1b0d6398 + .long 0x24000000,0x1964ce7d + .long 0x16000000,0x17b908bf + .type L(_FPI), @object + ASM_SIZE_DIRECTIVE(L(_FPI)) + +/* Coefficients of polynomials for */ +/* sin(x)~=x+x*x^2*(DP_SIN2_0+x^2*DP_SIN2_1) in low DP part, */ +/* cos(x)~=1+1*x^2*(DP_COS2_0+x^2*DP_COS2_1) in high DP part, */ +/* for |x|<2^-5. */ + .p2align 4 +L(DP_SINCOS2_0): + .long 0x5543d49d,0xbfc55555 + .long 0xff5cc6fd,0xbfdfffff + .type L(DP_SINCOS2_0), @object + ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_0)) + + .p2align 4 +L(DP_SINCOS2_1): + .long 0x75cec8c5,0x3f8110f4 + .long 0xb178dac5,0x3fa55514 + .type L(DP_SINCOS2_1), @object + ASM_SIZE_DIRECTIVE(L(DP_SINCOS2_1)) + + + .p2align 3 +L(DP_ZERONE): + .long 0x00000000,0x00000000 /* 0.0 */ + .long 0x00000000,0xbff00000 /* 1.0 */ + .type L(DP_ZERONE), @object + ASM_SIZE_DIRECTIVE(L(DP_ZERONE)) + + .p2align 3 +L(DP_ONES): + .long 0x00000000,0x3ff00000 /* +1.0 */ + .long 0x00000000,0xbff00000 /* -1.0 */ + .type L(DP_ONES), @object + ASM_SIZE_DIRECTIVE(L(DP_ONES)) + +/* Coefficients of polynomials for */ +/* sin(t)~=t+t*t^2*(S0+t^2*(S1+t^2*(S2+t^2*(S3+t^2*S4)))) in low DP part, */ +/* cos(t)~=1+1*t^2*(C0+t^2*(C1+t^2*(C2+t^2*(C3+t^2*C4)))) in high DP part, */ +/* for |t|<Pi/4. */ + .p2align 4 +L(DP_SC4): + .long 0x1674b58a,0xbe5a947e + .long 0xdd8844d7,0xbe923c97 + .type L(DP_SC4), @object + ASM_SIZE_DIRECTIVE(L(DP_SC4)) + + .p2align 4 +L(DP_SC3): + .long 0x64e6b5b4,0x3ec71d72 + .long 0x9ac43cc0,0x3efa00eb + .type L(DP_SC3), @object + ASM_SIZE_DIRECTIVE(L(DP_SC3)) + + .p2align 4 +L(DP_SC2): + .long 0x8b4bd1f9,0xbf2a019f + .long 0x348b6874,0xbf56c16b + .type L(DP_SC2), @object + ASM_SIZE_DIRECTIVE(L(DP_SC2)) + + .p2align 4 +L(DP_SC1): + .long 0x10c2688b,0x3f811111 + .long 0x545c50c7,0x3fa55555 + .type L(DP_SC1), @object + ASM_SIZE_DIRECTIVE(L(DP_SC1)) + + .p2align 4 +L(DP_SC0): + .long 0x55551cd9,0xbfc55555 + .long 0xfffe98ae,0xbfdfffff + .type L(DP_SC0), @object + ASM_SIZE_DIRECTIVE(L(DP_SC0)) + + .p2align 3 +L(DP_SMALL): + .long 0x00000000,0x3cd00000 /* 2^(-50) */ + .type L(DP_SMALL), @object + ASM_SIZE_DIRECTIVE(L(DP_SMALL)) + + .p2align 3 +L(DP_PIO4): + .long 0x54442d18,0x3fe921fb /* Pi/4 */ + .type L(DP_PIO4), @object + ASM_SIZE_DIRECTIVE(L(DP_PIO4)) + + .p2align 3 +L(DP_2POW52): + .long 0x00000000,0x43300000 /* +2^52 */ + .long 0x00000000,0xc3300000 /* -2^52 */ + .type L(DP_2POW52), @object + ASM_SIZE_DIRECTIVE(L(DP_2POW52)) + + .p2align 3 +L(DP_INVPIO4): + .long 0x6dc9c883,0x3ff45f30 /* 4/Pi */ + .type L(DP_INVPIO4), @object + ASM_SIZE_DIRECTIVE(L(DP_INVPIO4)) + + .p2align 3 +L(DP_PIO4HI): + .long 0x54000000,0xbfe921fb /* High part of Pi/4 */ + .type L(DP_PIO4HI), @object + ASM_SIZE_DIRECTIVE(L(DP_PIO4HI)) + + .p2align 3 +L(DP_PIO4LO): + .long 0x11A62633,0xbe010b46 /* Low part of Pi/4 */ + .type L(DP_PIO4LO), @object + ASM_SIZE_DIRECTIVE(L(DP_PIO4LO)) + + .p2align 2 +L(SP_INVPIO4): + .long 0x3fa2f983 /* 4/Pi */ + .type L(SP_INVPIO4), @object + ASM_SIZE_DIRECTIVE(L(SP_INVPIO4)) + + .p2align 4 +L(DP_ABS_MASK): /* Mask for getting DP absolute value */ + .long 0xffffffff,0x7fffffff + .long 0xffffffff,0x7fffffff + .type L(DP_ABS_MASK), @object + ASM_SIZE_DIRECTIVE(L(DP_ABS_MASK)) + + .p2align 3 +L(DP_HI_MASK): /* Mask for getting high 21 bits of DP value */ + .long 0x00000000,0xffffffff + .type L(DP_HI_MASK), @object + ASM_SIZE_DIRECTIVE(L(DP_HI_MASK)) + + .p2align 4 +L(SP_ABS_MASK): /* Mask for getting SP absolute value */ + .long 0x7fffffff,0x7fffffff + .long 0x7fffffff,0x7fffffff + .type L(SP_ABS_MASK), @object + ASM_SIZE_DIRECTIVE(L(SP_ABS_MASK)) + + .p2align 2 +L(SP_ONE): + .long 0x3f800000 /* 1.0 */ + .type L(SP_ONE), @object + ASM_SIZE_DIRECTIVE(L(SP_ONE)) + +weak_alias(__sincosf, sincosf) diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.c b/libc/sysdeps/x86_64/multiarch/init-arch.c index fb44dcfcf..fed5ab898 100644 --- a/libc/sysdeps/x86_64/multiarch/init-arch.c +++ b/libc/sysdeps/x86_64/multiarch/init-arch.c @@ -156,6 +156,9 @@ __init_cpu_features (void) /* Determine if AVX is usable. */ if (CPUID_AVX) __cpu_features.feature[index_AVX_Usable] |= bit_AVX_Usable; + /* Determine if FMA is usable. */ + if (CPUID_FMA) + __cpu_features.feature[index_FMA_Usable] |= bit_FMA_Usable; /* Determine if FMA4 is usable. */ if (CPUID_FMA4) __cpu_features.feature[index_FMA4_Usable] |= bit_FMA4_Usable; diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.h b/libc/sysdeps/x86_64/multiarch/init-arch.h index 45e265167..f33f1c81e 100644 --- a/libc/sysdeps/x86_64/multiarch/init-arch.h +++ b/libc/sysdeps/x86_64/multiarch/init-arch.h @@ -22,7 +22,8 @@ #define bit_Fast_Unaligned_Load (1 << 4) #define bit_Prefer_PMINUB_for_stringop (1 << 5) #define bit_AVX_Usable (1 << 6) -#define bit_FMA4_Usable (1 << 7) +#define bit_FMA_Usable (1 << 7) +#define bit_FMA4_Usable (1 << 8) /* CPUID Feature flags. */ #define bit_SSE2 (1 << 26) @@ -56,6 +57,7 @@ # define index_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE # define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1*FEATURE_SIZE # define index_AVX_Usable FEATURE_INDEX_1*FEATURE_SIZE +# define index_FMA_Usable FEATURE_INDEX_1*FEATURE_SIZE # define index_FMA4_Usable FEATURE_INDEX_1*FEATURE_SIZE #else /* __ASSEMBLER__ */ @@ -131,6 +133,8 @@ extern const struct cpu_features *__get_cpu_features (void) HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_OSXSAVE) # define CPUID_AVX \ HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_AVX) +# define CPUID_FMA \ + HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_FMA) # define CPUID_FMA4 \ HAS_CPUID_FLAG (COMMON_CPUID_INDEX_80000001, ecx, bit_FMA4) @@ -140,7 +144,6 @@ extern const struct cpu_features *__get_cpu_features (void) # define HAS_SSSE3 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSSE3) # define HAS_SSE4_1 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_1) # define HAS_SSE4_2 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_2) -# define HAS_FMA HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_FMA) # define index_Fast_Rep_String FEATURE_INDEX_1 # define index_Fast_Copy_Backward FEATURE_INDEX_1 @@ -148,6 +151,7 @@ extern const struct cpu_features *__get_cpu_features (void) # define index_Prefer_SSE_for_memop FEATURE_INDEX_1 # define index_Fast_Unaligned_Load FEATURE_INDEX_1 # define index_AVX_Usable FEATURE_INDEX_1 +# define index_FMA_Usable FEATURE_INDEX_1 # define index_FMA4_Usable FEATURE_INDEX_1 # define HAS_ARCH_FEATURE(name) \ @@ -159,6 +163,7 @@ extern const struct cpu_features *__get_cpu_features (void) # define HAS_PREFER_SSE_FOR_MEMOP HAS_ARCH_FEATURE (Prefer_SSE_for_memop) # define HAS_FAST_UNALIGNED_LOAD HAS_ARCH_FEATURE (Fast_Unaligned_Load) # define HAS_AVX HAS_ARCH_FEATURE (AVX_Usable) +# define HAS_FMA HAS_ARCH_FEATURE (FMA_Usable) # define HAS_FMA4 HAS_ARCH_FEATURE (FMA4_Usable) #endif /* __ASSEMBLER__ */ diff --git a/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S b/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S index a320a3e94..96380a46b 100644 --- a/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S +++ b/libc/sysdeps/x86_64/multiarch/strncmp-ssse3.S @@ -1,4 +1,6 @@ -#define USE_SSSE3 1 -#define STRCMP __strncmp_ssse3 -#define USE_AS_STRNCMP -#include "../strcmp.S" +#ifdef SHARED +# define USE_SSSE3 1 +# define STRCMP __strncmp_ssse3 +# define USE_AS_STRNCMP +# include "../strcmp.S" +#endif |