diff options
58 files changed, 2018 insertions, 855 deletions
@@ -1,5 +1,139 @@ +2006-03-27 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/kernel-features.h: Remove support for + architectures which moved to ports. + + * sysdeps/unix/sysv/linux/kernel-features.h: Add + __ASSUME_SET_ROBUST_LIST. + +2006-03-27 Jakub Jelinek <jakub@redhat.com> + + * wcsmbs/wchar.h (btowc, wctob): Don't optimize in C++. + +2006-03-24 David S. Miller <davem@sunset.davemloft.net> + + * sysdeps/sparc/sparc32/bits/atomic.h + (__v9_compare_and_exchange_val_32_acq): Add "memory" clobber. + * sysdeps/sparc/sparc32/sparcv9/bits/atomic.h + (__arch_compare_and_exchange_val_32_acq, atomic_exchange_acq): + Likewise. + * sysdeps/sparc/sparc64/bits/atomic.h + (__arch_compare_and_exchange_val_32_acq, + __arch_compare_and_exchange_val_64_acq, atomic_exchange_acq): Likewise. + +2006-03-24 Jakub Jelinek <jakub@redhat.com> + + * nis/nss_nisplus/nisplus-proto.c (_nss_create_tablename): Check the + return value of malloc rather than the static var again. + * nis/nss_nisplus/nisplus-grp.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-network.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-ethers.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-rpc.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-service.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-hosts.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-alias.c (_nss_create_tablename): Likewise. + * nis/nss_nisplus/nisplus-pwd.c (_nss_pwd_create_tablename): Likewise. + +2006-03-25 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/sparc/bits/poll.h: Add POLLMSG, + POLLREMOVE, and POLLRDHUP. + * sysdeps/unix/sysv/linux/bits/poll.h: Add POLLREMOVE and POLLRDHUP. + +2006-03-24 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/sparc/bits/fcntl.h: Define + LINUX_FADV_ASYNC_WRITE and LINUX_FADV_WRITE_WAIT. + * sysdeps/unix/sysv/linux/ia64/bits/fcntl.h: Likewise. + * sysdeps/unix/sysv/linux/sh/bits/fcntl.h: Likewise. + * sysdeps/unix/sysv/linux/i386/bits/fcntl.h: Likewise. + * sysdeps/unix/sysv/linux/s390/bits/fcntl.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h: Likewise. + * sysdeps/unix/sysv/linux/alpha/bits/fcntl.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h: Likewise. + +2006-03-17 Roland McGrath <roland@redhat.com> + + * elf/rtld.c (dl_main): Run final self-relocation after setting up TLS. + From Alexandre Oliva <aoliva@redhat.com>. + + * elf/tst-audit2.c: New file. + * elf/Makefile (tests): Add it. + ($(objpfx)tst-audit2.out): New target. + (tst-audit2-ENV): New variable. + + * elf/tst-leaks1.c: Include <stdio.h>. + +2006-03-16 Roland McGrath <roland@redhat.com> + + * sysdeps/unix/sysv/linux/alpha/getcontext.S (__getcontext_x): + Use .set noat to quiet assembler warning. + + * math/gen-libm-test.pl (parse_args): Take function name for pretty + output as an argument. + (generate_testfile): Pass it the name given in the START macro. + + [BZ #2466] + * math/libm-test.inc (llrint_test, llround_test): Fix last change to + protect large-precision cases with [LDBL_MANT_DIG > 100]. + (llrint_test_tonearest, llrint_test_towardzero): Likewise. + (llrint_test_downward, llrint_test_upward): Likewise. + +2006-03-15 Steven Munroe <sjmunroe@us.ibm.com> + Alan Modra <amodra@bigpond.net.au> + + [BZ #2466] + * math/libm-test.inc (llrint_test, llround_test) [TEST_LDOUBLE]: + Add new test values. + (llrint_test_tonearest, llrint_test_towardzero, llrint_test_downward, + llrint_test_upward): New functions. + (main): Call them. + + * sysdeps/ieee754/ldbl-128ibm/s_llrintl.c (__llrintl): Handle + rounding that spans doubles in IBM long double format. + * sysdeps/ieee754/ldbl-128ibm/s_llroundl.c (__llroundl): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_llrintl.S: Removed. + * sysdeps/powerpc/powerpc64/fpu/s_llroundl.S: Removed. + * sysdeps/powerpc/powerpc64/fpu/s_lrintl.S: Removed. + * sysdeps/powerpc/powerpc64/fpu/s_lroundl.S: Removed. + +2006-03-16 Roland McGrath <roland@redhat.com> + + * wcsmbs/wchar.h (__wcstol_internal, __wcstoul_internal): Declare these + only when we will use them, under [__OPTIMIZE__ && __GNUC__ >= 2]. + (__wcstoll_internal, __wcstoull_internal_defined): Likewise. + +2006-03-06 Steven Munroe <sjmunroe@us.ibm.com> + + * sysdeps/powerpc/powerpc32/fpu/fprsave.S: Add cfi_offset for spilling + of non-volatile floating-point registers to the stack (fp14-fp31). + * sysdeps/powerpc/powerpc32/gprsave0.S: Add cfi_offset for spilling of + non-volatile general-purpose registers to the stack (gpr13-gpr31). + * sysdeps/powerpc/powerpc64/dl-trampoline.S: Add cfi_offset + for non-volatiles gpr30 - grp31 spilled to the stack. + * sysdeps/powerpc/powerpc64/memcpy.S: Add cfi_offset for non-volatile + gpr31 spill to the stack. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S: + Add cfi_offset for non-volatile gpr31 spill to the stack. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Add cfi_offset + for non-volatiles gpr28 - grp31 spilled to the stack. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S: Add + cfi_adjust_cfa_offset when a frame is stacked. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S: + (__novec_setcontext) : Add cfi_offset for non-volatile gpr31 spill + add LR saved to the stack. Add cfi_adjust_cfa_offset when frame is + stacked. + (__setcontext) : Add cfi_offset for non-volatile gpr31 spill to + the stack. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S: + (__novec_swapcontext) : Add cfi_offset for non-volatile gpr31 spill + add LR saved to the stack. + (__swapcontext) : Add cfi_offset for non-volatile gpr31 spill add LR + saved to the stack. Add cfi_adjust_cfa_offset when frame is stacked. + 2006-03-07 Jakub Jelinek <jakub@redhat.com> + [BZ #2423] * math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test, round_test, trunc_test): Only run some of the new tests if LDBL_MANT_DIG > 100. @@ -7,36 +141,50 @@ 2006-03-03 Steven Munroe <sjmunroe@us.ibm.com> Alan Modra <amodra@bigpond.net.au> - [BZ #2423] - * math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test, - round_test, trunc_test): Add new tests. - * sysdeps/powerpc/fpu/fenv_libc.h (__fegetround, __fesetround): Define inline implementations. * sysdeps/powerpc/fpu/fegetround.c: Use __fegetround. * sysdeps/powerpc/fpu/fesetround.c: Use __fesetround. + * sysdeps/powerpc/fpu/math_ldbl.h: New file. + + [BZ #2423] + * math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test, + round_test, trunc_test): Add new tests. * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h - (EXTRACT_IBM_EXTENDED_MANTISSA, INSERT_IBM_EXTENDED_MANTISSA): - Removed, replaced with. + (EXTRACT_IBM_EXTENDED_MANTISSA, INSERT_IBM_EXTENDED_MANTISSA): + Removed, replaced with ... (ldbl_extract_mantissa, ldbl_insert_mantissa, ldbl_pack, ldbl_unpack, - ldbl_canonicalise, ldbl_nearbyint): Define inline utility - functions for IBM long double format. + ldbl_canonicalise, ldbl_nearbyint): New functions. * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Replace EXTRACT_IBM_EXTENDED_MANTISSA and INSERT_IBM_EXTENDED_MANTISSA with ldbl_extract_mantissa and ldbl_insert_mantissa. * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c (__ieee754_rem_pio2l): Replace EXTRACT_IBM_EXTENDED_MANTISSA with ldbl_extract_mantissa. - (ldbl_extract_mantissa, ldbl_insert_mantissa): Defined. - + (ldbl_extract_mantissa, ldbl_insert_mantissa): New inline functions. * sysdeps/ieee754/ldbl-128ibm/s_ceill.c (__ceill): Handle rounding that spans doubles in IBM long double format. * sysdeps/ieee754/ldbl-128ibm/s_floorl.c: Likewise. * sysdeps/ieee754/ldbl-128ibm/s_rintl.c: Likewise. * sysdeps/ieee754/ldbl-128ibm/s_roundl.c: Likewise. * sysdeps/ieee754/ldbl-128ibm/s_truncl.c: Likewise. - * sysdeps/powerpc/fpu/math_ldbl.h: New file. - * sysdeps/powerpc/powerpc64/fpu/s_rintl.S: Removed. + * sysdeps/powerpc/powerpc64/fpu/s_rintl.S: File removed. + +2004-12-09 Randolph Chung <tausq@debian.org> + + * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_UTIMES): Don't + define for hppa, which doesn't support this syscall. + +2006-03-13 Jakub Jelinek <jakub@redhat.com> + + [BZ #2451] + * elf/dl-load.c (open_verify): Add free_name argument, if true, free + name before calling lose. + (open_path): Adjust caller. + (_dl_map_object): Adjust callers. Free name_copy before calling + _dl_signal_error. + * elf/Makefile: Add rules to build and run tst-leaks1. + * elf/tst-leaks1.c: New test. 2006-03-06 Roland McGrath <roland@redhat.com> diff --git a/elf/Makefile b/elf/Makefile index 791341758e..3b4ef26d45 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -91,7 +91,7 @@ distribute := rtld-Rules \ order2mod1.c order2mod2.c order2mod3.c order2mod4.c \ tst-stackguard1.c tst-stackguard1-static.c \ tst-array5.c tst-array5-static.c tst-array5dep.c \ - tst-array5.exp + tst-array5.exp tst-leaks1.c CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables @@ -139,7 +139,7 @@ vpath %.c ../locale/programs endif endif -tests = tst-tls1 tst-tls2 tst-tls9 +tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 ifeq (yes,$(have-initfini-array)) tests += tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 endif @@ -168,7 +168,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ tst-dlmodcount tst-dlopenrpath tst-deep1 \ tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ - unload3 unload4 unload5 unload6 tst-audit1 tst-global1 order2 \ + unload3 unload4 unload5 unload6 tst-global1 order2 \ + tst-audit1 tst-audit2 \ tst-stackguard1 # reldep9 test-srcs = tst-pathopt @@ -180,6 +181,7 @@ endif ifeq (yesyes,$(have-fpie)$(build-shared)) tests: $(objpfx)tst-pie1.out endif +tests: $(objpfx)tst-leaks1-mem modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ testobj1_1 failobj constload2 constload3 unloadmod \ dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \ @@ -878,6 +880,9 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so $(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so +$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so +tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + $(objpfx)tst-global1: $(libdl) $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so @@ -895,3 +900,9 @@ order2mod2.so-no-z-defs = yes tst-stackguard1-ARGS = --command "$(built-program-cmd) --child" tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" + +$(objpfx)tst-leaks1: $(libdl) +$(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@ + +tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace diff --git a/elf/dl-load.c b/elf/dl-load.c index bba1c83ba0..088954a04f 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1,5 +1,6 @@ /* Map in a shared object's segments from the file. - Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006 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 @@ -1554,7 +1555,7 @@ print_search_path (struct r_search_path_elem **list, user might want to know about this. */ static int open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, - int whatcode, bool *found_other_class) + int whatcode, bool *found_other_class, bool free_name) { /* This is the expected ELF header. */ #define ELF32_CLASS ELFCLASS32 @@ -1635,6 +1636,12 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, errstring = (errval == 0 ? N_("file too short") : N_("cannot read file data")); call_lose: + if (free_name) + { + char *realname = (char *) name; + name = strdupa (realname); + free (realname); + } lose (errval, fd, name, NULL, NULL, errstring); } @@ -1821,7 +1828,8 @@ open_path (const char *name, size_t namelen, int preloaded, if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf (" trying file=%s\n", buf); - fd = open_verify (buf, fbp, loader, whatcode, found_other_class); + fd = open_verify (buf, fbp, loader, whatcode, found_other_class, + false); if (this_dir->status[cnt] == unknown) { if (fd != -1) @@ -2098,7 +2106,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, { fd = open_verify (cached, &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, - LA_SER_CONFIG, &found_other_class); + LA_SER_CONFIG, &found_other_class, false); if (__builtin_expect (fd != -1, 1)) { realname = local_strdup (cached); @@ -2136,7 +2144,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, { fd = open_verify (realname, &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, - &found_other_class); + &found_other_class, true); if (__builtin_expect (fd, 0) == -1) free (realname); } @@ -2166,8 +2174,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, if ((name_copy = local_strdup (name)) == NULL || (l = _dl_new_object (name_copy, name, type, loader, mode, nsid)) == NULL) - _dl_signal_error (ENOMEM, name, NULL, - N_("cannot create shared object descriptor")); + { + free (name_copy); + _dl_signal_error (ENOMEM, name, NULL, + N_("cannot create shared object descriptor")); + } /* Signal that this is a faked entry. */ l->l_faked = 1; /* Since the descriptor is initialized with zero we do not diff --git a/elf/rtld.c b/elf/rtld.c index 76d129a0a0..68fe809700 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1,5 +1,5 @@ /* Run time dynamic linker. - Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2004, 2005, 2006 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 @@ -2200,7 +2200,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", #ifndef HP_TIMING_NONAVAIL hp_timing_t start; hp_timing_t stop; - hp_timing_t add; #endif /* If we are profiling we also must do lazy reloaction. */ @@ -2255,19 +2254,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", if (__builtin_expect (GL(dl_profile_map) != NULL, 0)) /* We must prepare the profiling. */ _dl_start_profile (); - - if (rtld_multiple_ref) - { - /* There was an explicit ref to the dynamic linker as a shared lib. - Re-relocate ourselves with user-controlled symbol definitions. */ - HP_TIMING_NOW (start); - /* Mark the link map as not yet relocated again. */ - GL(dl_rtld_map).l_relocated = 0; - _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (add, start, stop); - HP_TIMING_ACCUM_NT (relocate_time, add); - } } #ifndef NONTLS_INIT_TP @@ -2296,6 +2282,30 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", NONTLS_INIT_TP; #endif + if (! prelinked && rtld_multiple_ref) + { + /* There was an explicit ref to the dynamic linker as a shared lib. + Re-relocate ourselves with user-controlled symbol definitions. + + We must do this after TLS initialization in case after this + re-relocation, we might call a user-supplied function + (e.g. calloc from _dl_relocate_object) that uses TLS data. */ + +#ifndef HP_TIMING_NONAVAIL + hp_timing_t start; + hp_timing_t stop; + hp_timing_t add; +#endif + + HP_TIMING_NOW (start); + /* Mark the link map as not yet relocated again. */ + GL(dl_rtld_map).l_relocated = 0; + _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); + HP_TIMING_NOW (stop); + HP_TIMING_DIFF (add, start, stop); + HP_TIMING_ACCUM_NT (relocate_time, add); + } + #ifdef SHARED /* Auditing checkpoint: we have added all objects. */ if (__builtin_expect (GLRO(dl_naudit) > 0, 0)) diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c new file mode 100644 index 0000000000..fd089b6f64 --- /dev/null +++ b/elf/tst-audit2.c @@ -0,0 +1,50 @@ +/* Test case for early TLS initialization in dynamic linker. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if HAVE___THREAD +# define MAGIC1 0xabcdef72 +# define MAGIC2 0xd8675309 +static __thread unsigned int magic[] = { MAGIC1, MAGIC2 }; +#endif + +#undef calloc + +/* This calloc definition will be called by the dynamic linker itself. + We test that it has initialized our TLS block by the time it does so. */ + +void * +calloc (size_t n, size_t m) +{ +#if HAVE___THREAD + if (magic[0] != MAGIC1 || magic[1] != MAGIC2) + { + printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC1, MAGIC2); + abort (); + } + magic[0] = MAGIC2; + magic[1] = MAGIC1; +#endif + + n *= m; + void *ptr = malloc (n); + if (ptr != NULL) + memset (ptr, '\0', n); + return ptr; +} + +int +main (void) +{ +#if HAVE___THREAD + if (magic[1] != MAGIC1 || magic[0] != MAGIC2) + { + printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1); + return 1; + } +#endif + + return 0; +} diff --git a/elf/tst-leaks1.c b/elf/tst-leaks1.c new file mode 100644 index 0000000000..36e4aee9cf --- /dev/null +++ b/elf/tst-leaks1.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <dlfcn.h> +#include <mcheck.h> +#include <stdlib.h> + +int +main (void) +{ + mtrace (); + + int ret = 0; + for (int i = 0; i < 10; i++) + { + void *h = dlopen (i < 5 ? "./tst-leaks1.c" + : "$ORIGIN/tst-leaks1.o", RTLD_LAZY); + if (h != NULL) + { + puts ("dlopen unexpectedly succeeded"); + ret = 1; + dlclose (h); + } + } + + return ret; +} diff --git a/fedora/branch.mk b/fedora/branch.mk index e3f3348c17..9f35fe0f79 100644 --- a/fedora/branch.mk +++ b/fedora/branch.mk @@ -3,5 +3,5 @@ glibc-branch := fedora glibc-base := HEAD DIST_BRANCH := devel COLLECTION := dist-fc4 -fedora-sync-date := 2006-03-06 12:39 UTC -fedora-sync-tag := fedora-glibc-20060306T1239 +fedora-sync-date := 2006-03-28 09:00 UTC +fedora-sync-tag := fedora-glibc-20060328T0900 diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in index c3c2c0de58..987ee270cb 100644 --- a/fedora/glibc.spec.in +++ b/fedora/glibc.spec.in @@ -1,4 +1,4 @@ -%define glibcrelease 4 +%define glibcrelease 5 %define auxarches i586 i686 athlon sparcv9 alphaev6 %define prelinkarches noarch %define xenarches i686 athlon @@ -1336,6 +1336,12 @@ rm -f *.filelist* %endif %changelog +* Tue Mar 28 Jakub Jelinek <jakub@redhat.com> 2.4-5 +- update from CVS + - pshared robust mutex support + - fix btowc and bwtoc in C++ (#186410) + - fix NIS+ (#186592) + - don't declare __wcsto*l_internal for non-GCC or if not -O1+ (#185667) - don't mention nscd failures on 2.0 kernels (#185335) * Tue Mar 7 2006 Roland McGrath <roland@redhat.com> 2.4-4 diff --git a/math/gen-libm-test.pl b/math/gen-libm-test.pl index 26f819a884..a63f62a1cb 100755 --- a/math/gen-libm-test.pl +++ b/math/gen-libm-test.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright (C) 1999 Free Software Foundation, Inc. +# Copyright (C) 1999, 2006 Free Software Foundation, Inc. # This file is part of the GNU C Library. # Contributed by Andreas Jaeger <aj@suse.de>, 1999. @@ -234,7 +234,7 @@ sub special_functions { # Parse the arguments to TEST_x_y sub parse_args { - my ($file, $descr, $args) = @_; + my ($file, $descr, $fct, $args) = @_; my (@args, $str, $descr_args, $descr_res, @descr); my ($current_arg, $cline, $i); my ($pre, $post, @special); @@ -248,7 +248,7 @@ sub parse_args { @args = split /,\s*/, $args; - $call = "$args[0] ("; + $call = "$fct ("; # Generate first the string that's shown to the user $current_arg = 1; @@ -423,7 +423,7 @@ sub parse_args { sub generate_testfile { my ($input, $output) = @_; my ($lasttext); - my (@args, $i, $str); + my (@args, $i, $str, $thisfct); open INPUT, $input or die ("Can't open $input: $!"); open OUTPUT, ">$output" or die ("Can't open $output: $!"); @@ -436,11 +436,12 @@ sub generate_testfile { my ($descr, $args); chop; ($descr, $args) = ($_ =~ /TEST_(\w+)\s*\((.*)\)/); - &parse_args (\*OUTPUT, $descr, $args); + &parse_args (\*OUTPUT, $descr, $thisfct, $args); next; } # START (function) if (/START/) { + ($thisfct) = ($_ =~ /START\s*\((.*)\)/); print OUTPUT " init_max_error ();\n"; next; } diff --git a/math/libm-test.inc b/math/libm-test.inc index b144796f2a..58ab2f5e59 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -3331,6 +3331,22 @@ llrint_test (void) TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL); TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL); +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL); + + TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL); +#endif + TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL); TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL); TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL); @@ -3343,6 +3359,22 @@ llrint_test (void) TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL); TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL); +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL); + + TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL); +#endif + TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL); TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL); TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL); @@ -3354,11 +3386,570 @@ llrint_test (void) TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL); TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL); TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L); + TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL); + TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL); +# endif #endif END (llrint); } +static void +llrint_test_tonearest (void) +{ + int save_round_mode; + START (llrint_tonearest); + + save_round_mode = fegetround (); + + if (!fesetround (FE_TONEAREST)) + { + TEST_f_L (llrint, 0.0, 0); + TEST_f_L (llrint, minus_zero, 0); + TEST_f_L (llrint, 0.2L, 0); + TEST_f_L (llrint, -0.2L, 0); + + TEST_f_L (llrint, 1.4L, 1); + TEST_f_L (llrint, -1.4L, -1); + + TEST_f_L (llrint, 8388600.3L, 8388600); + TEST_f_L (llrint, -8388600.3L, -8388600); + + TEST_f_l (llrint, 1071930.0008, 1071930); + + /* Test boundary conditions. */ + /* 0x1FFFFF */ + TEST_f_L (llrint, 2097151.0,2097151LL); + /* 0x800000 */ + TEST_f_L (llrint, 8388608.0, 8388608LL); + /* 0x1000000 */ + TEST_f_L (llrint, 16777216.0, 16777216LL); + /* 0x20000000000 */ + TEST_f_L (llrint, 2199023255552.0, 2199023255552LL); + /* 0x40000000000 */ + TEST_f_L (llrint, 4398046511104.0, 4398046511104LL); + /* 0x1000000000000 */ + TEST_f_L (llrint, 281474976710656.0, 281474976710656LL); + /* 0x10000000000000 */ + TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL); + /* 0x10000080000000 */ + TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL); + /* 0x20000000000000 */ + TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL); + /* 0x80000000000000 */ + TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL); + /* 0x100000000000000 */ + TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL); +#ifdef TEST_LDOUBLE + /* The input can only be represented in long double. */ + TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL); + + TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL); + + TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL); +#endif + + TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL); + + TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL); + + TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL); +#endif + + TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL); + TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL); + + TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL); + TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L); + TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL); + TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL); +# endif +#endif + } + + fesetround (save_round_mode); + + END (llrint_tonearest); +} + +static void +llrint_test_towardzero (void) +{ + int save_round_mode; + START (llrint_towardzero); + + save_round_mode = fegetround (); + + if (!fesetround (FE_TOWARDZERO)) + { + TEST_f_L (llrint, 0.0, 0); + TEST_f_L (llrint, minus_zero, 0); + TEST_f_L (llrint, 0.2L, 0); + TEST_f_L (llrint, -0.2L, 0); + + TEST_f_L (llrint, 1.4L, 1); + TEST_f_L (llrint, -1.4L, -1); + + TEST_f_L (llrint, 8388600.3L, 8388600); + TEST_f_L (llrint, -8388600.3L, -8388600); + + TEST_f_l (llrint, 1071930.0008, 1071930); + + /* Test boundary conditions. */ + /* 0x1FFFFF */ + TEST_f_L (llrint, 2097151.0,2097151LL); + /* 0x800000 */ + TEST_f_L (llrint, 8388608.0, 8388608LL); + /* 0x1000000 */ + TEST_f_L (llrint, 16777216.0, 16777216LL); + /* 0x20000000000 */ + TEST_f_L (llrint, 2199023255552.0, 2199023255552LL); + /* 0x40000000000 */ + TEST_f_L (llrint, 4398046511104.0, 4398046511104LL); + /* 0x1000000000000 */ + TEST_f_L (llrint, 281474976710656.0, 281474976710656LL); + /* 0x10000000000000 */ + TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL); + /* 0x10000080000000 */ + TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL); + /* 0x20000000000000 */ + TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL); + /* 0x80000000000000 */ + TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL); + /* 0x100000000000000 */ + TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL); +#ifdef TEST_LDOUBLE + /* The input can only be represented in long double. */ + TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL); + + TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL); + TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL); + + TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL); + TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL); +#endif + + TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL); + + TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL); + + TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL); +#endif + + TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL); + TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL); + + TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL); + TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL); + TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL); + TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L); + TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL); +# endif +#endif + } + + fesetround (save_round_mode); + + END (llrint_towardzero); +} + +static void +llrint_test_downward (void) +{ + int save_round_mode; + START (llrint_downward); + + save_round_mode = fegetround (); + + if (!fesetround (FE_DOWNWARD)) + { + TEST_f_L (llrint, 0.0, 0); + TEST_f_L (llrint, minus_zero, 0); + TEST_f_L (llrint, 0.2L, 0); + TEST_f_L (llrint, -0.2L, -1); + + TEST_f_L (llrint, 1.4L, 1); + TEST_f_L (llrint, -1.4L, -2); + + TEST_f_L (llrint, 8388600.3L, 8388600); + TEST_f_L (llrint, -8388600.3L, -8388601); + + TEST_f_l (llrint, 1071930.0008, 1071930); + + /* Test boundary conditions. */ + /* 0x1FFFFF */ + TEST_f_L (llrint, 2097151.0,2097151LL); + /* 0x800000 */ + TEST_f_L (llrint, 8388608.0, 8388608LL); + /* 0x1000000 */ + TEST_f_L (llrint, 16777216.0, 16777216LL); + /* 0x20000000000 */ + TEST_f_L (llrint, 2199023255552.0, 2199023255552LL); + /* 0x40000000000 */ + TEST_f_L (llrint, 4398046511104.0, 4398046511104LL); + /* 0x1000000000000 */ + TEST_f_L (llrint, 281474976710656.0, 281474976710656LL); + /* 0x10000000000000 */ + TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL); + /* 0x10000080000000 */ + TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL); + /* 0x20000000000000 */ + TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL); + /* 0x80000000000000 */ + TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL); + /* 0x100000000000000 */ + TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL); +#ifdef TEST_LDOUBLE + /* The input can only be represented in long double. */ + TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL); + + TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL); + TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL); + + TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.25L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370496.5L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL); + + TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370498LL); + TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL); + + TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL); + + TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL); + TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL); + + TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.25L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740992.5L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL); + + TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740994LL); + TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL); + + TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL); + TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL); + + TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.25L, -72057594037927937LL); + TEST_f_L (llrint, -72057594037927936.5L, -72057594037927937LL); + TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL); + TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL); + TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775807LL); + TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L); + TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775807LL); + TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL); + TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL); +# endif +#endif + } + + fesetround (save_round_mode); + + END (llrint_downward); +} + +static void +llrint_test_upward (void) +{ + int save_round_mode; + START (llrint_upward); + + save_round_mode = fegetround (); + + if (!fesetround (FE_UPWARD)) + { + TEST_f_L (llrint, 0.0, 0); + TEST_f_L (llrint, minus_zero, 0); + TEST_f_L (llrint, 0.2L, 1); + TEST_f_L (llrint, -0.2L, 0); + + TEST_f_L (llrint, 1.4L, 2); + TEST_f_L (llrint, -1.4L, -1); + + TEST_f_L (llrint, 8388600.3L, 8388601); + TEST_f_L (llrint, -8388600.3L, -8388600); +#ifndef TEST_FLOAT + TEST_f_l (llrint, 1071930.0008, 1071931); +#endif + /* Test boundary conditions. */ + /* 0x1FFFFF */ + TEST_f_L (llrint, 2097151.0,2097151LL); + /* 0x800000 */ + TEST_f_L (llrint, 8388608.0, 8388608LL); + /* 0x1000000 */ + TEST_f_L (llrint, 16777216.0, 16777216LL); + /* 0x20000000000 */ + TEST_f_L (llrint, 2199023255552.0, 2199023255552LL); + /* 0x40000000000 */ + TEST_f_L (llrint, 4398046511104.0, 4398046511104LL); + /* 0x1000000000000 */ + TEST_f_L (llrint, 281474976710656.0, 281474976710656LL); + /* 0x10000000000000 */ + TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL); + /* 0x10000080000000 */ + TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL); + /* 0x20000000000000 */ + TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL); + /* 0x80000000000000 */ + TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL); + /* 0x100000000000000 */ + TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL); +#ifdef TEST_LDOUBLE + /* The input can only be represented in long double. */ + TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.25L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370496.5L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL); + + TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370497LL); + TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370498LL); + TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL); + TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL); + TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL); + + TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL); + + TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL); + TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL); + TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL); + TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL); + TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL); + + TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.25L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740992.5L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL); + + TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740994LL); + TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL); + TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL); + TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL); + + TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL); + + TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL); + TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL); + TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL); + TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL); + + TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL); + TEST_f_L (llrint, 72057594037927936.25L, 72057594037927937LL); + TEST_f_L (llrint, 72057594037927936.5L, 72057594037927937LL); + TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL); + TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL); + + TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL); + TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL); + TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL); + +# if LDBL_MANT_DIG > 100 + TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL); + TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL); + TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775807L); + TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL); + TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL); + TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL); +# endif +#endif + } + + fesetround (save_round_mode); + + END (llrint_upward); +} + static void log_test (void) @@ -3597,6 +4188,22 @@ llround_test (void) TEST_f_L (llround, 4503599627370496.75L, 4503599627370497LL); TEST_f_L (llround, 4503599627370497.5L, 4503599627370498LL); +# if LDBL_MANT_DIG > 100 + TEST_f_L (llround, 4503599627370495.4999999999999L, 4503599627370495LL); + TEST_f_L (llround, 4503599627370496.4999999999999L, 4503599627370496LL); + TEST_f_L (llround, 4503599627370497.4999999999999L, 4503599627370497LL); + TEST_f_L (llround, 4503599627370494.5000000000001L, 4503599627370495LL); + TEST_f_L (llround, 4503599627370495.5000000000001L, 4503599627370496LL); + TEST_f_L (llround, 4503599627370496.5000000000001L, 4503599627370497LL); + + TEST_f_L (llround, -4503599627370495.4999999999999L, -4503599627370495LL); + TEST_f_L (llround, -4503599627370496.4999999999999L, -4503599627370496LL); + TEST_f_L (llround, -4503599627370497.4999999999999L, -4503599627370497LL); + TEST_f_L (llround, -4503599627370494.5000000000001L, -4503599627370495LL); + TEST_f_L (llround, -4503599627370495.5000000000001L, -4503599627370496LL); + TEST_f_L (llround, -4503599627370496.5000000000001L, -4503599627370497LL); +# endif + TEST_f_L (llround, -4503599627370495.5L, -4503599627370496LL); TEST_f_L (llround, -4503599627370496.25L, -4503599627370496LL); TEST_f_L (llround, -4503599627370496.5L, -4503599627370497LL); @@ -3609,6 +4216,22 @@ llround_test (void) TEST_f_L (llround, 9007199254740992.75L, 9007199254740993LL); TEST_f_L (llround, 9007199254740993.5L, 9007199254740994LL); +# if LDBL_MANT_DIG > 100 + TEST_f_L (llround, 9007199254740991.4999999999999L, 9007199254740991LL); + TEST_f_L (llround, 9007199254740992.4999999999999L, 9007199254740992LL); + TEST_f_L (llround, 9007199254740993.4999999999999L, 9007199254740993LL); + TEST_f_L (llround, 9007199254740991.5000000000001L, 9007199254740992LL); + TEST_f_L (llround, 9007199254740992.5000000000001L, 9007199254740993LL); + TEST_f_L (llround, 9007199254740993.5000000000001L, 9007199254740994LL); + + TEST_f_L (llround, -9007199254740991.4999999999999L, -9007199254740991LL); + TEST_f_L (llround, -9007199254740992.4999999999999L, -9007199254740992LL); + TEST_f_L (llround, -9007199254740993.4999999999999L, -9007199254740993LL); + TEST_f_L (llround, -9007199254740991.5000000000001L, -9007199254740992LL); + TEST_f_L (llround, -9007199254740992.5000000000001L, -9007199254740993LL); + TEST_f_L (llround, -9007199254740993.5000000000001L, -9007199254740994LL); +# endif + TEST_f_L (llround, -9007199254740991.5L, -9007199254740992LL); TEST_f_L (llround, -9007199254740992.25L, -9007199254740992LL); TEST_f_L (llround, -9007199254740992.5L, -9007199254740993LL); @@ -4051,6 +4674,12 @@ rint_test (void) TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); # endif +# if LDBL_MANT_DIG > 100 + TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); +# endif + TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); @@ -4077,6 +4706,26 @@ rint_test (void) TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); # endif +# if LDBL_MANT_DIG > 100 + TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); + + TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); + TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); + + TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); + TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); +# endif + TEST_f_f (rint, 9007199254740991.5L, 9007199254740992.0L); TEST_f_f (rint, 9007199254740992.25L, 9007199254740992.0L); TEST_f_f (rint, 9007199254740992.5L, 9007199254740992.0L); @@ -4117,66 +4766,66 @@ rint_test_tonearest (void) int save_round_mode; START (rint_tonearest); - save_round_mode = fegetround(); + save_round_mode = fegetround (); if (!fesetround (FE_TONEAREST)) - { - TEST_f_f (rint, 2.0, 2.0); - TEST_f_f (rint, 1.5, 2.0); - TEST_f_f (rint, 1.0, 1.0); - TEST_f_f (rint, 0.5, 0.0); - TEST_f_f (rint, 0.0, 0.0); - TEST_f_f (rint, minus_zero, minus_zero); - TEST_f_f (rint, -0.5, -0.0); - TEST_f_f (rint, -1.0, -1.0); - TEST_f_f (rint, -1.5, -2.0); - TEST_f_f (rint, -2.0, -2.0); - TEST_f_f (rint, 0.1, 0.0); - TEST_f_f (rint, 0.25, 0.0); - TEST_f_f (rint, 0.625, 1.0); - TEST_f_f (rint, -0.1, -0.0); - TEST_f_f (rint, -0.25, -0.0); - TEST_f_f (rint, -0.625, -1.0); + { + TEST_f_f (rint, 2.0, 2.0); + TEST_f_f (rint, 1.5, 2.0); + TEST_f_f (rint, 1.0, 1.0); + TEST_f_f (rint, 0.5, 0.0); + TEST_f_f (rint, 0.0, 0.0); + TEST_f_f (rint, minus_zero, minus_zero); + TEST_f_f (rint, -0.5, -0.0); + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -2.0); + TEST_f_f (rint, -2.0, -2.0); + TEST_f_f (rint, 0.1, 0.0); + TEST_f_f (rint, 0.25, 0.0); + TEST_f_f (rint, 0.625, 1.0); + TEST_f_f (rint, -0.1, -0.0); + TEST_f_f (rint, -0.25, -0.0); + TEST_f_f (rint, -0.625, -1.0); #ifdef TEST_LDOUBLE - /* The result can only be represented in long double. */ - TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); - TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); + /* The result can only be represented in long double. */ + TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); - TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); # endif - TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); - TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); + TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); - TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); - - TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); - TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); - TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); - TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); - - TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); - TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); - TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); - TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); + TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); + + TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); + TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); + + TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); + TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); # endif #endif - } + } - fesetround(save_round_mode); + fesetround (save_round_mode); END (rint_tonearest); } @@ -4187,66 +4836,66 @@ rint_test_towardzero (void) int save_round_mode; START (rint_towardzero); - save_round_mode = fegetround(); + save_round_mode = fegetround (); if (!fesetround (FE_TOWARDZERO)) - { - TEST_f_f (rint, 2.0, 2.0); - TEST_f_f (rint, 1.5, 1.0); - TEST_f_f (rint, 1.0, 1.0); - TEST_f_f (rint, 0.5, 0.0); - TEST_f_f (rint, 0.0, 0.0); - TEST_f_f (rint, minus_zero, minus_zero); - TEST_f_f (rint, -0.5, -0.0); - TEST_f_f (rint, -1.0, -1.0); - TEST_f_f (rint, -1.5, -1.0); - TEST_f_f (rint, -2.0, -2.0); - TEST_f_f (rint, 0.1, 0.0); - TEST_f_f (rint, 0.25, 0.0); - TEST_f_f (rint, 0.625, 0.0); - TEST_f_f (rint, -0.1, -0.0); - TEST_f_f (rint, -0.25, -0.0); - TEST_f_f (rint, -0.625, -0.0); + { + TEST_f_f (rint, 2.0, 2.0); + TEST_f_f (rint, 1.5, 1.0); + TEST_f_f (rint, 1.0, 1.0); + TEST_f_f (rint, 0.5, 0.0); + TEST_f_f (rint, 0.0, 0.0); + TEST_f_f (rint, minus_zero, minus_zero); + TEST_f_f (rint, -0.5, -0.0); + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -1.0); + TEST_f_f (rint, -2.0, -2.0); + TEST_f_f (rint, 0.1, 0.0); + TEST_f_f (rint, 0.25, 0.0); + TEST_f_f (rint, 0.625, 0.0); + TEST_f_f (rint, -0.1, -0.0); + TEST_f_f (rint, -0.25, -0.0); + TEST_f_f (rint, -0.625, -0.0); #ifdef TEST_LDOUBLE - /* The result can only be represented in long double. */ - TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L); - TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L); + /* The result can only be represented in long double. */ + TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L); - TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L); - TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L); + TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L); # endif - TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L); - TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L); - TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L); - TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L); - - TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); - TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); - TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L); - TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L); - - TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); - TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); - TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L); - TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L); + TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L); + + TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); + TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L); + TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L); + + TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); + TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L); + TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L); # endif #endif - } + } - fesetround(save_round_mode); + fesetround (save_round_mode); END (rint_towardzero); } @@ -4257,66 +4906,66 @@ rint_test_downward (void) int save_round_mode; START (rint_downward); - save_round_mode = fegetround(); + save_round_mode = fegetround (); if (!fesetround (FE_DOWNWARD)) - { - TEST_f_f (rint, 2.0, 2.0); - TEST_f_f (rint, 1.5, 1.0); - TEST_f_f (rint, 1.0, 1.0); - TEST_f_f (rint, 0.5, 0.0); - TEST_f_f (rint, 0.0, 0.0); - TEST_f_f (rint, minus_zero, minus_zero); - TEST_f_f (rint, -0.5, -1.0); - TEST_f_f (rint, -1.0, -1.0); - TEST_f_f (rint, -1.5, -2.0); - TEST_f_f (rint, -2.0, -2.0); - TEST_f_f (rint, 0.1, 0.0); - TEST_f_f (rint, 0.25, 0.0); - TEST_f_f (rint, 0.625, 0.0); - TEST_f_f (rint, -0.1, -1.0); - TEST_f_f (rint, -0.25, -1.0); - TEST_f_f (rint, -0.625, -1.0); + { + TEST_f_f (rint, 2.0, 2.0); + TEST_f_f (rint, 1.5, 1.0); + TEST_f_f (rint, 1.0, 1.0); + TEST_f_f (rint, 0.5, 0.0); + TEST_f_f (rint, 0.0, 0.0); + TEST_f_f (rint, minus_zero, minus_zero); + TEST_f_f (rint, -0.5, -1.0); + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -2.0); + TEST_f_f (rint, -2.0, -2.0); + TEST_f_f (rint, 0.1, 0.0); + TEST_f_f (rint, 0.25, 0.0); + TEST_f_f (rint, 0.625, 0.0); + TEST_f_f (rint, -0.1, -1.0); + TEST_f_f (rint, -0.25, -1.0); + TEST_f_f (rint, -0.625, -1.0); #ifdef TEST_LDOUBLE - /* The result can only be represented in long double. */ - TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L); - TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L); + /* The result can only be represented in long double. */ + TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L); - TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L); - TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L); + TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L); # endif - TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.25L, -4503599627370497.0L); - TEST_f_f (rint, -4503599627370496.5L, -4503599627370497.0L); - TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); - TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); + TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.25L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370496.5L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); - TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); - - TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); - TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); - TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L); - TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L); - - TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740993.0L); - TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740994.0L); - TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); - TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); + TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); + + TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); + TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L); + TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L); + + TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740994.0L); + TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); # endif #endif - } + } - fesetround(save_round_mode); + fesetround (save_round_mode); END (rint_downward); } @@ -4327,66 +4976,66 @@ rint_test_upward (void) int save_round_mode; START (rint_upward); - save_round_mode = fegetround(); + save_round_mode = fegetround (); if (!fesetround (FE_UPWARD)) - { - TEST_f_f (rint, 2.0, 2.0); - TEST_f_f (rint, 1.5, 2.0); - TEST_f_f (rint, 1.0, 1.0); - TEST_f_f (rint, 0.5, 1.0); - TEST_f_f (rint, 0.0, 0.0); - TEST_f_f (rint, minus_zero, minus_zero); - TEST_f_f (rint, -0.5, -0.0); - TEST_f_f (rint, -1.0, -1.0); - TEST_f_f (rint, -1.5, -1.0); - TEST_f_f (rint, -2.0, -2.0); - TEST_f_f (rint, 0.1, 1.0); - TEST_f_f (rint, 0.25, 1.0); - TEST_f_f (rint, 0.625, 1.0); - TEST_f_f (rint, -0.1, -0.0); - TEST_f_f (rint, -0.25, -0.0); - TEST_f_f (rint, -0.625, -0.0); + { + TEST_f_f (rint, 2.0, 2.0); + TEST_f_f (rint, 1.5, 2.0); + TEST_f_f (rint, 1.0, 1.0); + TEST_f_f (rint, 0.5, 1.0); + TEST_f_f (rint, 0.0, 0.0); + TEST_f_f (rint, minus_zero, minus_zero); + TEST_f_f (rint, -0.5, -0.0); + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -1.0); + TEST_f_f (rint, -2.0, -2.0); + TEST_f_f (rint, 0.1, 1.0); + TEST_f_f (rint, 0.25, 1.0); + TEST_f_f (rint, 0.625, 1.0); + TEST_f_f (rint, -0.1, -0.0); + TEST_f_f (rint, -0.25, -0.0); + TEST_f_f (rint, -0.625, -0.0); #ifdef TEST_LDOUBLE - /* The result can only be represented in long double. */ - TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.25L, 4503599627370497.0L); - TEST_f_f (rint, 4503599627370496.5L, 4503599627370497.0L); - TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); - TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); + /* The result can only be represented in long double. */ + TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.25L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370496.5L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); - TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); - TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); + TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); # endif - TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L); - TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L); - TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L); # if LDBL_MANT_DIG > 100 - TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L); - TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L); - TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L); - - TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740993.0L); - TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740994.0L); - TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); - TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); - TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); - - TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); - TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); - TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L); - TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L); - TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L); + TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L); + TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L); + + TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740994.0L); + TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); + TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); + + TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); + TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); + TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L); + TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L); + TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L); # endif #endif - } + } - fesetround(save_round_mode); + fesetround (save_round_mode); END (rint_upward); } @@ -4419,7 +5068,7 @@ round_test (void) /* The result can only be represented in long double. */ TEST_f_f (round, 4503599627370495.5L, 4503599627370496.0L); TEST_f_f (round, 4503599627370496.25L, 4503599627370496.0L); - TEST_f_f (round, 4503599627370496.5L, 4503599627370497.0L); + TEST_f_f (round, 4503599627370496.5L, 4503599627370497.0L); TEST_f_f (round, 4503599627370496.75L, 4503599627370497.0L); TEST_f_f (round, 4503599627370497.5L, 4503599627370498.0L); # if LDBL_MANT_DIG > 100 @@ -4428,10 +5077,10 @@ round_test (void) TEST_f_f (round, 4503599627370496.5000000000001L, 4503599627370497.0L); # endif - TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L); - TEST_f_f (round, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L); + TEST_f_f (round, -4503599627370496.25L, -4503599627370496.0L); TEST_f_f (round, -4503599627370496.5L, -4503599627370497.0L); - TEST_f_f (round, -4503599627370496.75L, -4503599627370497.0L); + TEST_f_f (round, -4503599627370496.75L, -4503599627370497.0L); TEST_f_f (round, -4503599627370497.5L, -4503599627370498.0L); # if LDBL_MANT_DIG > 100 TEST_f_f (round, -4503599627370494.5000000000001L, -4503599627370495.0L); @@ -4870,7 +5519,7 @@ trunc_test (void) TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L); TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L); # endif - + TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L); TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L); TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L); @@ -4883,6 +5532,12 @@ trunc_test (void) TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L); # endif +# if LDBL_MANT_DIG > 100 + TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L); + TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L); + TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L); +# endif + TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L); TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L); TEST_f_f (trunc, 9007199254740992.5L, 9007199254740992.0L); @@ -4929,7 +5584,7 @@ trunc_test (void) TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L); TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L); TEST_f_f (trunc, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L); - TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L); + TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L); #endif END (trunc); @@ -5315,6 +5970,10 @@ main (int argc, char **argv) rint_test_upward (); lrint_test (); llrint_test (); + llrint_test_tonearest (); + llrint_test_towardzero (); + llrint_test_downward (); + llrint_test_upward (); round_test (); lround_test (); llround_test (); diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c index 6aa93ab3bc..d7926e1566 100644 --- a/nis/nss_nisplus/nisplus-alias.c +++ b/nis/nss_nisplus/nisplus-alias.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -51,7 +52,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "mail_aliases.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c index fcc550e743..ca0a9e2481 100644 --- a/nis/nss_nisplus/nisplus-ethers.c +++ b/nis/nss_nisplus/nisplus-ethers.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000-2003,2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -94,7 +94,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "ethers.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c index 423f7e7291..624b20610a 100644 --- a/nis/nss_nisplus/nisplus-grp.c +++ b/nis/nss_nisplus/nisplus-grp.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1997, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -47,7 +48,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "group.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c index 81f8a984dc..bf002d6dd7 100644 --- a/nis/nss_nisplus/nisplus-hosts.c +++ b/nis/nss_nisplus/nisplus-hosts.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1997-2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -186,7 +186,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "hosts.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c index dc6b99e505..960c0558e9 100644 --- a/nis/nss_nisplus/nisplus-network.c +++ b/nis/nss_nisplus/nisplus-network.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000-2003,2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -148,7 +148,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "networks.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c index 585a4844ad..a3370aa85e 100644 --- a/nis/nss_nisplus/nisplus-proto.c +++ b/nis/nss_nisplus/nisplus-proto.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -147,7 +148,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "protocols.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c index 97679dd349..6c222ede02 100644 --- a/nis/nss_nisplus/nisplus-pwd.c +++ b/nis/nss_nisplus/nisplus-pwd.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1999,2001,2002,2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -44,7 +45,7 @@ _nss_pwd_create_tablename (int *errnop) static const char prefix[] = "passwd.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (pwd_tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c index 98baa5f7fc..f6ab3fbd87 100644 --- a/nis/nss_nisplus/nisplus-rpc.c +++ b/nis/nss_nisplus/nisplus-rpc.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997. @@ -144,7 +145,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "rpc.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c index 848e5f4dd8..c47dc09a06 100644 --- a/nis/nss_nisplus/nisplus-service.c +++ b/nis/nss_nisplus/nisplus-service.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. @@ -151,7 +152,7 @@ _nss_create_tablename (int *errnop) static const char prefix[] = "services.org_dir."; char *p = malloc (sizeof (prefix) + local_dir_len); - if (tablename_val == NULL) + if (p == NULL) { *errnop = errno; return NSS_STATUS_TRYAGAIN; diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 678a419aca..64cea204e3 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,35 @@ +2006-03-27 Ulrich Drepper <drepper@redhat.com> + + * allocatestack.c (allocate_stack): Always initialize robust_head. + * descr.h: Define struct robust_list_head. + (struct pthread): Use robust_list_head in robust mutex list definition. + Adjust ENQUEUE_MUTEX and DEQUEUE_MUTEX. + * init.c [!__ASSUME_SET_ROBUST_LIST] (__set_robust_list_avail): Define. + (__pthread_initialize_minimal_internal): Register robust_list with + the kernel. + * pthreadP.h: Remove PRIVATE_ from PTHREAD_MUTEX_ROBUST_* names. + Declare __set_robust_list_avail. + * pthread_create.c (start_thread): Register robust_list of new thread. + [!__ASSUME_SET_ROBUST_LIST]: If robust_list is not empty wake up + waiters. + * pthread_mutex_destroy.c: For robust mutexes don't look at the + number of users, it's unreliable. + * pthread_mutex_init.c: Allow use of pshared robust mutexes if + set_robust_list syscall is available. + * pthread_mutex_consistent.c: Adjust for PTHREAD_MUTEX_ROBUST_* rename. + * pthread_mutex_lock.c: Simplify robust mutex code a bit. + Set robust_head.list_op_pending before trying to lock a robust mutex. + * pthread_mutex_timedlock.c: Likewise. + * pthread_mutex_trylock.c: Likewise. + * pthread_mutex_unlock.c: Likewise for unlocking. + * Makefile (tests): Add tst-robust8. + * tst-robust8.c: New file. + +2006-03-08 Andreas Schwab <schwab@suse.de> + + * sysdeps/unix/sysv/linux/ia64/dl-sysdep.h + (DL_SYSINFO_IMPLEMENTATION): Add missing newline. + 2006-03-05 Roland McGrath <roland@redhat.com> * configure (libc_add_on): Disable add-on when $add_ons_automatic = yes diff --git a/nptl/Makefile b/nptl/Makefile index 31b5ace92e..e430b8d6cb 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -206,7 +206,7 @@ tests = tst-typesizes \ tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ tst-cond20 tst-cond21 \ tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \ - tst-robust6 tst-robust7 \ + tst-robust6 tst-robust7 tst-robust8 \ tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \ tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \ tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \ diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 046a2470fc..a3ed1a33d3 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -365,12 +365,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* The process ID is also the same as that of the caller. */ pd->pid = THREAD_GETMEM (THREAD_SELF, pid); - /* List of robust mutexes. */ -#ifdef __PTHREAD_MUTEX_HAVE_PREV - pd->robust_list.__prev = &pd->robust_list; -#endif - pd->robust_list.__next = &pd->robust_list; - /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) { @@ -505,12 +499,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* The process ID is also the same as that of the caller. */ pd->pid = THREAD_GETMEM (THREAD_SELF, pid); - /* List of robust mutexes. */ -#ifdef __PTHREAD_MUTEX_HAVE_PREV - pd->robust_list.__prev = &pd->robust_list; -#endif - pd->robust_list.__next = &pd->robust_list; - /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) { @@ -634,6 +622,18 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, stillborn thread could be canceled while the lock is taken. */ pd->lock = LLL_LOCK_INITIALIZER; + /* The robust mutex lists also need to be initialized + unconditionally because the cleanup for the previous stack owner + might have happened in the kernel. */ + pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock) + - offsetof (pthread_mutex_t, + __data.__list.__next)); + pd->robust_head.list_op_pending = NULL; +#ifdef __PTHREAD_MUTEX_HAVE_PREV + pd->robust_prev = &pd->robust_head; +#endif + pd->robust_head.list = &pd->robust_head; + /* We place the thread descriptor at the end of the stack. */ *pdp = pd; diff --git a/nptl/descr.h b/nptl/descr.h index 80251b920b..f89d3240da 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -102,6 +102,15 @@ struct xid_command }; +/* Data structure used by the kernel to find robust futexes. */ +struct robust_list_head +{ + void *list; + long int futex_offset; + void *list_op_pending; +}; + + /* Thread descriptor data structure. */ struct pthread { @@ -136,25 +145,43 @@ struct pthread /* List of robust mutexes the thread is holding. */ #ifdef __PTHREAD_MUTEX_HAVE_PREV - __pthread_list_t robust_list; + void *robust_prev; + struct robust_list_head robust_head; + + /* The list above is strange. It is basically a double linked list + but the pointer to the next/previous element of the list points + in the middle of the object, the __next element. Whenever + casting to __pthread_list_t we need to adjust the pointer + first. */ +# define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next)) # define ENQUEUE_MUTEX(mutex) \ do { \ - __pthread_list_t *next = THREAD_GETMEM (THREAD_SELF, robust_list.__next); \ - next->__prev = &mutex->__data.__list; \ - mutex->__data.__list.__next = next; \ - mutex->__data.__list.__prev = &THREAD_SELF->robust_list; \ - THREAD_SETMEM (THREAD_SELF, robust_list.__next, &mutex->__data.__list); \ + __pthread_list_t *next = (THREAD_GETMEM (THREAD_SELF, robust_head.list) \ + - QUEUE_PTR_ADJUST); \ + next->__prev = (void *) &mutex->__data.__list.__next; \ + mutex->__data.__list.__next = (void *) &next->__next; \ + mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head; \ + THREAD_SETMEM (THREAD_SELF, robust_head.list, \ + &mutex->__data.__list.__next); \ } while (0) # define DEQUEUE_MUTEX(mutex) \ do { \ - mutex->__data.__list.__next->__prev = mutex->__data.__list.__prev; \ - mutex->__data.__list.__prev->__next = mutex->__data.__list.__next; \ + __pthread_list_t *next = (__pthread_list_t *) \ + ((char *) mutex->__data.__list.__next - QUEUE_PTR_ADJUST); \ + next->__prev = mutex->__data.__list.__prev; \ + __pthread_list_t *prev = (__pthread_list_t *) \ + ((char *) mutex->__data.__list.__prev - QUEUE_PTR_ADJUST); \ + prev->__next = mutex->__data.__list.__next; \ mutex->__data.__list.__prev = NULL; \ mutex->__data.__list.__next = NULL; \ } while (0) #else - __pthread_slist_t robust_list; + union + { + __pthread_slist_t robust_list; + struct robust_list_head robust_head; + }; # define ENQUEUE_MUTEX(mutex) \ do { \ diff --git a/nptl/init.c b/nptl/init.c index cb63ff7a6d..4db3e0c828 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -60,6 +60,15 @@ size_t __static_tls_size; size_t __static_tls_align_m1; +#ifndef __ASSUME_SET_ROBUST_LIST +/* Negative if we do not have the system call and we can use it. */ +int __set_robust_list_avail; +# define set_robust_list_not_avail() \ + __set_robust_list_avail = -1 +#else +# define set_robust_list_not_avail() do { } while (0) +#endif + /* Version of the library, used in libthread_db to detect mismatches. */ static const char nptl_version[] __attribute_used__ = VERSION; @@ -247,10 +256,6 @@ __pthread_initialize_minimal_internal (void) struct pthread *pd = THREAD_SELF; INTERNAL_SYSCALL_DECL (err); pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid); -#ifdef __PTHREAD_MUTEX_HAVE_PREV - pd->robust_list.__prev = &pd->robust_list; -#endif - pd->robust_list.__next = &pd->robust_list; THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]); THREAD_SETMEM (pd, user_stack, true); if (LLL_LOCK_INITIALIZER != 0) @@ -259,6 +264,21 @@ __pthread_initialize_minimal_internal (void) THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset)); #endif + /* Initialize the robust mutex data. */ +#ifdef __PTHREAD_MUTEX_HAVE_PREV + pd->robust_prev = &pd->robust_head; +#endif + pd->robust_head.list = &pd->robust_head; +#ifdef __NR_set_robust_list + pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock) + - offsetof (pthread_mutex_t, + __data.__list.__next)); + int res = INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head, + sizeof (struct robust_list_head)); + if (INTERNAL_SYSCALL_ERROR_P (res, err)) +#endif + set_robust_list_not_avail (); + /* Set initial thread's stack block from 0 up to __libc_stack_end. It will be bigger than it actually is, but for unwind.c/pt-longjmp.c purposes this is good enough. */ diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index a4d6d1a1ae..7b3da83786 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -31,6 +31,7 @@ #include <internaltypes.h> #include <pthread-functions.h> #include <atomic.h> +#include <kernel-features.h> /* Atomic operations on TLS memory. */ @@ -60,13 +61,13 @@ /* Internal mutex type value. */ enum { - PTHREAD_MUTEX_ROBUST_PRIVATE_NP = 16, - PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP - = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP - = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP - = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_ADAPTIVE_NP, + PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16, + PTHREAD_MUTEX_ROBUST_RECURSIVE_NP + = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP + = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP + = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP, PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP = 32, PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP = 64 }; @@ -128,6 +129,11 @@ hidden_proto (__pthread_keys) /* Number of threads running. */ extern unsigned int __nptl_nthreads attribute_hidden; +#ifndef __ASSUME_SET_ROBUST_LIST +/* Negative if we do not have the system call and we can use it. */ +extern int __set_robust_list_avail attribute_hidden; +#endif + /* The library can run in debugging mode where it performs a lot more tests. */ extern int __pthread_debug attribute_hidden; @@ -504,4 +510,15 @@ extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden; # define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name); #endif + +#ifndef __NR_set_robust_list +/* XXX For the time being... Once we can rely on the kernel headers + having the definition remove these lines. */ +# if defined __i386__ +# define __NR_set_robust_list 311 +# elif defined __x86_64__ +# define __NR_set_robust_list 273 +# endif +#endif + #endif /* pthreadP.h */ diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index f3d90ecebf..71365a17e8 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -229,6 +229,19 @@ start_thread (void *arg) /* Initialize resolver state pointer. */ __resp = &pd->res; +#ifdef __NR_set_robust_list +# ifndef __ASSUME_SET_ROBUST_LIST + if (__set_robust_list_avail >= 0) +# endif + { + INTERNAL_SYSCALL_DECL (err); + /* This call should never fail because the initial call in init.c + succeeded. */ + INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head, + sizeof (struct robust_list_head)); + } +#endif + /* This is where the try/finally block should be created. For compilers without that support we do use setjmp. */ struct pthread_unwind_buf unwind_buf; @@ -310,35 +323,34 @@ start_thread (void *arg) the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE. */ atomic_bit_set (&pd->cancelhandling, EXITING_BIT); +#ifndef __ASSUME_SET_ROBUST_LIST /* If this thread has any robust mutexes locked, handle them now. */ -#if __WORDSIZE == 64 - __pthread_list_t *robust = pd->robust_list.__next; -#else +# if __WORDSIZE == 64 + void *robust = pd->robust_head.list; +# else __pthread_slist_t *robust = pd->robust_list.__next; -#endif - if (__builtin_expect (robust != &pd->robust_list, 0)) +# endif +/* We let the kernel do the notification if it is able to do so. */ + if (__set_robust_list_avail < 0 + && __builtin_expect (robust != &pd->robust_head, 0)) { do { struct __pthread_mutex_s *this = (struct __pthread_mutex_s *) - ((char *) robust - offsetof (struct __pthread_mutex_s, __list)); - robust = robust->__next; + ((char *) robust - offsetof (struct __pthread_mutex_s, + __list.__next)); + robust = *((void **) robust); - this->__list.__next = NULL; -#ifdef __PTHREAD_MUTEX_HAVE_PREV +# ifdef __PTHREAD_MUTEX_HAVE_PREV this->__list.__prev = NULL; -#endif +# endif + this->__list.__next = NULL; lll_robust_mutex_dead (this->__lock); } - while (robust != &pd->robust_list); - - /* Clean up so that the thread descriptor can be reused. */ - pd->robust_list.__next = &pd->robust_list; -#ifdef __PTHREAD_MUTEX_HAVE_PREV - pd->robust_list.__prev = &pd->robust_list; -#endif + while (robust != &pd->robust_head); } +#endif /* If the thread is detached free the TCB. */ if (IS_DETACHED (pd)) diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c index 0cfe972da0..d4f287b755 100644 --- a/nptl/pthread_mutex_consistent.c +++ b/nptl/pthread_mutex_consistent.c @@ -26,7 +26,7 @@ pthread_mutex_consistent_np (mutex) pthread_mutex_t *mutex; { /* Test whether this is a robust mutex with a dead owner. */ - if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_PRIVATE_NP) == 0 + if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT) return EINVAL; diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c index 19a647a846..7829979f35 100644 --- a/nptl/pthread_mutex_destroy.c +++ b/nptl/pthread_mutex_destroy.c @@ -25,15 +25,9 @@ int __pthread_mutex_destroy (mutex) pthread_mutex_t *mutex; { - if (mutex->__data.__nusers != 0) - { - if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_PRIVATE_NP) != 0 - && (mutex->__data.__lock & FUTEX_OWNER_DIED) != 0 - && mutex->__data.__nusers == 1) - goto dead_robust_mutex; - - return EBUSY; - } + if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + && mutex->__data.__nusers != 0) + return EBUSY; /* Set to an invalid value. */ dead_robust_mutex: diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c index f984d90ae4..c25e4035e5 100644 --- a/nptl/pthread_mutex_init.c +++ b/nptl/pthread_mutex_init.c @@ -22,7 +22,6 @@ #include <string.h> #include "pthreadP.h" - static const struct pthread_mutexattr default_attr = { /* Default is a normal mutex, not shared between processes. */ @@ -42,10 +41,6 @@ __pthread_mutex_init (mutex, mutexattr) imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr; /* Sanity checks. */ - // XXX For now we cannot implement robust mutexes if they are shared. - if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0 - && (imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0) - return ENOTSUP; // XXX For now we don't support priority inherited or priority protected // XXX mutexes. if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) @@ -57,8 +52,18 @@ __pthread_mutex_init (mutex, mutexattr) /* Copy the values from the attribute. */ mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; + if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0) - mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_PRIVATE_NP; + { +#ifndef __ASSUME_SET_ROBUST_LIST + if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0 + && __set_robust_list_avail < 0) + return ENOTSUP; +#endif + + mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; + } + switch ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) >> PTHREAD_MUTEXATTR_PROTOCOL_SHIFT) { diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c index dd22567c71..06eef49c71 100644 --- a/nptl/pthread_mutex_lock.c +++ b/nptl/pthread_mutex_lock.c @@ -108,25 +108,33 @@ __pthread_mutex_lock (mutex) assert (mutex->__data.__owner == 0); break; - case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP: + case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP: + case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP: + case PTHREAD_MUTEX_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); + oldval = mutex->__data.__lock; do { + again: if ((oldval & FUTEX_OWNER_DIED) != 0) { /* The previous owner died. Try locking the mutex. */ - int newval; - while ((newval - = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, - id, oldval)) - != oldval) + int newval = id; +#ifdef NO_INCR + newval |= FUTEX_WAITERS; +#endif + + newval + = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, + newval, oldval); + + if (newval != oldval) { - if ((newval & FUTEX_OWNER_DIED) == 0) - goto normal; oldval = newval; + goto again; } /* We got the mutex. */ @@ -135,6 +143,7 @@ __pthread_mutex_lock (mutex) mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; ENQUEUE_MUTEX (mutex); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); /* Note that we deliberately exit here. If we fall through to the end of the function __nusers would be @@ -149,18 +158,23 @@ __pthread_mutex_lock (mutex) return EOWNERDEAD; } - normal: /* Check whether we already hold the mutex. */ - if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK) - == id, 0)) + if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0)) { if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP) - return EDEADLK; + == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + return EDEADLK; + } if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP) + == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + /* Just bump the counter. */ if (__builtin_expect (mutex->__data.__count + 1 == 0, 0)) /* Overflow of the counter. */ @@ -180,6 +194,7 @@ __pthread_mutex_lock (mutex) /* This mutex is now not recoverable. */ mutex->__data.__count = 0; lll_mutex_unlock (mutex->__data.__lock); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return ENOTRECOVERABLE; } } @@ -187,6 +202,7 @@ __pthread_mutex_lock (mutex) mutex->__data.__count = 1; ENQUEUE_MUTEX (mutex); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); break; default: diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index b69caedc7c..7c48c7ce6b 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -103,25 +103,27 @@ pthread_mutex_timedlock (mutex, abstime) } break; - case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP: + case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP: + case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP: + case PTHREAD_MUTEX_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); + oldval = mutex->__data.__lock; do { + again: if ((oldval & FUTEX_OWNER_DIED) != 0) { /* The previous owner died. Try locking the mutex. */ - int newval; - while ((newval - = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, - id, oldval)) - != oldval) + int newval + = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, + id, oldval); + if (newval != oldval) { - if ((newval & FUTEX_OWNER_DIED) == 0) - goto normal; oldval = newval; + goto again; } /* We got the mutex. */ @@ -130,6 +132,7 @@ pthread_mutex_timedlock (mutex, abstime) mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; ENQUEUE_MUTEX (mutex); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); /* Note that we deliberately exist here. If we fall through to the end of the function __nusers would be @@ -138,18 +141,23 @@ pthread_mutex_timedlock (mutex, abstime) return EOWNERDEAD; } - normal: /* Check whether we already hold the mutex. */ - if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK) - == id, 0)) + if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0)) { if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP) - return EDEADLK; + == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + return EDEADLK; + } if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP) + == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + /* Just bump the counter. */ if (__builtin_expect (mutex->__data.__count + 1 == 0, 0)) /* Overflow of the counter. */ @@ -170,6 +178,7 @@ pthread_mutex_timedlock (mutex, abstime) /* This mutex is now not recoverable. */ mutex->__data.__count = 0; lll_mutex_unlock (mutex->__data.__lock); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return ENOTRECOVERABLE; } @@ -182,6 +191,7 @@ pthread_mutex_timedlock (mutex, abstime) mutex->__data.__count = 1; ENQUEUE_MUTEX (mutex); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); break; default: diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c index 5a13ea6925..148a6e919f 100644 --- a/nptl/pthread_mutex_trylock.c +++ b/nptl/pthread_mutex_trylock.c @@ -77,25 +77,28 @@ __pthread_mutex_trylock (mutex) return 0; - case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP: + case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP: + case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP: + case PTHREAD_MUTEX_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); + oldval = mutex->__data.__lock; do { + again: if ((oldval & FUTEX_OWNER_DIED) != 0) { /* The previous owner died. Try locking the mutex. */ - int newval; - while ((newval - = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, - id, oldval)) - != oldval) + int newval + = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, + id, oldval); + + if (newval != oldval) { - if ((newval & FUTEX_OWNER_DIED) == 0) - goto normal; oldval = newval; + goto again; } /* We got the mutex. */ @@ -104,6 +107,7 @@ __pthread_mutex_trylock (mutex) mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT; ENQUEUE_MUTEX (mutex); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); /* Note that we deliberately exist here. If we fall through to the end of the function __nusers would be @@ -112,18 +116,23 @@ __pthread_mutex_trylock (mutex) return EOWNERDEAD; } - normal: /* Check whether we already hold the mutex. */ - if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK) - == id, 0)) + if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0)) { if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP) - return EDEADLK; + == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + return EDEADLK; + } if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP) + == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + NULL); + /* Just bump the counter. */ if (__builtin_expect (mutex->__data.__count + 1 == 0, 0)) /* Overflow of the counter. */ @@ -137,7 +146,11 @@ __pthread_mutex_trylock (mutex) oldval = lll_robust_mutex_trylock (mutex->__data.__lock, id); if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0) - return EBUSY; + { + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); + + return EBUSY; + } robust: if (__builtin_expect (mutex->__data.__owner @@ -147,12 +160,14 @@ __pthread_mutex_trylock (mutex) mutex->__data.__count = 0; if (oldval == id) lll_mutex_unlock (mutex->__data.__lock); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return ENOTRECOVERABLE; } } while ((oldval & FUTEX_OWNER_DIED) != 0); ENQUEUE_MUTEX (mutex); + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); mutex->__data.__owner = id; ++mutex->__data.__nusers; diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c index d41eefe34c..bf9aa7625f 100644 --- a/nptl/pthread_mutex_unlock.c +++ b/nptl/pthread_mutex_unlock.c @@ -63,10 +63,12 @@ __pthread_mutex_unlock_usercnt (mutex, decr) lll_mutex_unlock (mutex->__data.__lock); break; - case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP: + case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP: /* Recursive mutex. */ if ((mutex->__data.__lock & FUTEX_TID_MASK) - == THREAD_GETMEM (THREAD_SELF, tid)) + == THREAD_GETMEM (THREAD_SELF, tid) + && __builtin_expect (mutex->__data.__owner + == PTHREAD_MUTEX_INCONSISTENT, 0)) { if (--mutex->__data.__count != 0) /* We still hold the mutex. */ @@ -84,9 +86,9 @@ __pthread_mutex_unlock_usercnt (mutex, decr) goto robust; - case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP: + case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP: + case PTHREAD_MUTEX_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP: if ((mutex->__data.__lock & FUTEX_TID_MASK) != THREAD_GETMEM (THREAD_SELF, tid) || ! lll_mutex_islocked (mutex->__data.__lock)) @@ -102,6 +104,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr) robust: /* Remove mutex from the list. */ + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, + &mutex->__data.__list.__next); DEQUEUE_MUTEX (mutex); mutex->__data.__owner = newowner; @@ -111,6 +115,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr) /* Unlock. */ lll_robust_mutex_unlock (mutex->__data.__lock); + + THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); break; default: diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h index af835c44b1..525b622a68 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h +++ b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h @@ -1,5 +1,5 @@ /* System-specific settings for dynamic linker code. IA-64 version. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2006 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 @@ -57,7 +57,7 @@ extern int _dl_sysinfo_break attribute_hidden; ".body\n\t" \ "break 0x100000;\n\t" \ "br.ret.sptk.many b6;\n\t" \ - ".endp _dl_sysinfo_break" \ + ".endp _dl_sysinfo_break\n\t" \ ".previous"); #endif diff --git a/nptl/tst-robust8.c b/nptl/tst-robust8.c new file mode 100644 index 0000000000..19682e594f --- /dev/null +++ b/nptl/tst-robust8.c @@ -0,0 +1,264 @@ +#include <pthread.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/wait.h> + + + + +static void prepare (void); +#define PREPARE(argc, argv) prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#define TIMEOUT 3 +#include "../test-skeleton.c" + + +static int fd; +#define N 100 + +static void +prepare (void) +{ + fd = create_temp_file ("tst-robust8", NULL); + if (fd == -1) + exit (1); +} + + +#define THESIGNAL SIGKILL +#define ROUNDS 5 +#define THREADS 9 + + +static const struct timespec before = { 0, 0 }; + + +static pthread_mutex_t *map; + + +static void * +tf (void *arg) +{ + long int nr = (long int) arg; + int fct = nr % 3; + + uint8_t state[N]; + memset (state, '\0', sizeof (state)); + + while (1) + { + int r = random () % N; + if (state[r] == 0) + { + int e; + + switch (fct) + { + case 0: + e = pthread_mutex_lock (&map[r]); + if (e != 0) + { + printf ("mutex_lock of %d in thread %ld failed with %d\n", + r, nr, e); + exit (1); + } + state[r] = 1; + break; + case 1: + e = pthread_mutex_timedlock (&map[r], &before); + if (e != 0 && e != ETIMEDOUT) + { + printf ("\ +mutex_timedlock of %d in thread %ld failed with %d\n", + r, nr, e); + exit (1); + } + break; + default: + e = pthread_mutex_trylock (&map[r]); + if (e != 0 && e != EBUSY) + { + printf ("mutex_trylock of %d in thread %ld failed with %d\n", + r, nr, e); + exit (1); + } + break; + } + + if (e == EOWNERDEAD) + pthread_mutex_consistent_np (&map[r]); + + if (e == 0 || e == EOWNERDEAD) + state[r] = 1; + } + else + { + int e = pthread_mutex_unlock (&map[r]); + if (e != 0) + { + printf ("mutex_unlock of %d in thread %ld failed with %d\n", + r, nr, e); + exit (1); + } + + state[r] = 0; + } + } +} + + +static void +child (int round) +{ + for (int thread = 1; thread <= THREADS; ++thread) + { + pthread_t th; + if (pthread_create (&th, NULL, tf, (void *) (long int) thread) != 0) + { + printf ("cannot create thread %d in round %d\n", thread, round); + exit (1); + } + } + + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 1000000000 / ROUNDS; + while (nanosleep (&ts, &ts) != 0) + /* nothing */; + + /* Time to die. */ + kill (getpid (), THESIGNAL); + + /* We better never get here. */ + abort (); +} + + +static int +do_test (void) +{ + if (ftruncate (fd, N * sizeof (pthread_mutex_t)) != 0) + { + puts ("cannot size new file"); + return 1; + } + + map = mmap (NULL, N * sizeof (pthread_mutex_t), PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + { + puts ("mapping failed"); + return 1; + } + + pthread_mutexattr_t ma; + if (pthread_mutexattr_init (&ma) != 0) + { + puts ("mutexattr_init failed"); + return 0; + } + if (pthread_mutexattr_setrobust_np (&ma, PTHREAD_MUTEX_ROBUST_NP) != 0) + { + puts ("mutexattr_setrobust failed"); + return 1; + } + if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("mutexattr_setpshared failed"); + return 1; + } + + for (int round = 1; round <= ROUNDS; ++round) + { + for (int n = 0; n < N; ++n) + { + int e = pthread_mutex_init (&map[n], &ma); + if (e == ENOTSUP) + { + puts ("cannot support pshared robust mutexes"); + return 0; + } + if (e != 0) + { + printf ("mutex_init %d in round %d failed\n", n + 1, round); + return 1; + } + } + + pid_t p = fork (); + if (p == -1) + { + printf ("fork in round %d failed\n", round); + return 1; + } + if (p == 0) + child (round); + + int status; + if (TEMP_FAILURE_RETRY (waitpid (p, &status, 0)) != p) + { + printf ("waitpid in round %d failed\n", round); + return 1; + } + if (!WIFSIGNALED (status)) + { + printf ("child did not die of a signal in round %d\n", round); + return 1; + } + if (WTERMSIG (status) != THESIGNAL) + { + printf ("child did not die of signal %d in round %d\n", + THESIGNAL, round); + return 1; + } + + for (int n = 0; n < N; ++n) + { + int e = pthread_mutex_lock (&map[n]); + if (e != 0 && e != EOWNERDEAD) + { + printf ("mutex_lock %d failed in round %d\n", n + 1, round); + return 1; + } + } + + for (int n = 0; n < N; ++n) + if (pthread_mutex_unlock (&map[n]) != 0) + { + printf ("mutex_unlock %d failed in round %d\n", n + 1, round); + return 1; + } + + for (int n = 0; n < N; ++n) + { + int e = pthread_mutex_destroy (&map[n]); + if (e != 0) + { + printf ("mutex_destroy %d in round %d failed with %d\n", + n + 1, round, e); + printf("nusers = %d\n", (int) map[n].__data.__nusers); + return 1; + } + } + } + + if (pthread_mutexattr_destroy (&ma) != 0) + { + puts ("mutexattr_destroy failed"); + return 1; + } + + if (munmap (map, N * sizeof (pthread_mutex_t)) != 0) + { + puts ("munmap failed"); + return 1; + } + + return 0; +} diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c index bacf1bee0d..7228489098 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c @@ -22,6 +22,7 @@ when it's coded in C. */ #include <math.h> +#include <fenv_libc.h> #include <math_ldbl_opt.h> #include <float.h> #include <ieee754.h> @@ -36,89 +37,114 @@ __llrintl (x) long double x; #endif { - static const double TWO52 = 4503599627370496.0L; - union ibm_extended_long_double u; - long long result = __LONG_LONG_MAX__; + double xh, xl; + long long res, hi, lo; + int save_round; - u.d = x; + ldbl_unpack (x, &xh, &xl); - if (fabs (u.dd[0]) < TWO52) + /* Limit the range of values handled by the conversion to long long. + We do this because we aren't sure whether that conversion properly + raises FE_INVALID. */ + if (__builtin_expect + ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1) +#if !defined (FE_INVALID) + || 1 +#endif + ) { - double high = u.dd[0]; - if (high > 0.0) - { - high += TWO52; - high -= TWO52; - if (high == -0.0) high = 0.0; - } - else if (high < 0.0) + save_round = fegetround (); + + if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0)) { - high -= TWO52; - high += TWO52; - if (high == 0.0) high = -0.0; + /* When XH is 9223372036854775808.0, converting to long long will + overflow, resulting in an invalid operation. However, XL might + be negative and of sufficient magnitude that the overall long + double is in fact in range. Avoid raising an exception. In any + case we need to convert this value specially, because + the converted value is not exactly represented as a double + thus subtracting HI from XH suffers rounding error. */ + hi = __LONG_LONG_MAX__; + xh = 1.0; } - result = high; - } - else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) - { - double high, low, tau; - long long lowint; - /* In this case we have to round the low double and handle any - adjustment to the high double that may be caused by rounding - (up). This is complicated by the fact that the high double - may already be rounded and the low double may have the - opposite sign to compensate. */ - if (u.dd[0] > 0.0) + else { - if (u.dd[1] > 0.0) - { - /* If the high/low doubles are the same sign then simply - round the low double. */ - high = u.dd[0]; - low = u.dd[1]; - } - else if (u.dd[1] < 0.0) - { - /* Else the high double is pre rounded and we need to - adjust for that. */ - - tau = nextafter (u.dd[0], 0.0); - tau = (u.dd[0] - tau) * 2.0; - high = u.dd[0] - tau; - low = u.dd[1] + tau; - } - low += TWO52; - low -= TWO52; + hi = (long long) xh; + xh -= hi; } - else if (u.dd[0] < 0.0) + ldbl_canonicalize (&xh, &xl); + + lo = (long long) xh; + + /* Peg at max/min values, assuming that the above conversions do so. + Strictly speaking, we can return anything for values that overflow, + but this is more useful. */ + res = hi + lo; + + /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */ + if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0)) + goto overflow; + + xh -= lo; + ldbl_canonicalize (&xh, &xl); + + hi = res; + switch (save_round) { - if (u.dd[1] < 0.0) - { - /* If the high/low doubles are the same sign then simply - round the low double. */ - high = u.dd[0]; - low = u.dd[1]; - } - else if (u.dd[1] > 0.0) - { - /* Else the high double is pre rounded and we need to - adjust for that. */ - tau = nextafter (u.dd[0], 0.0); - tau = (u.dd[0] - tau) * 2.0; - high = u.dd[0] - tau; - low = u.dd[1] + tau; - } - low = TWO52 - low; - low = -(low - TWO52); + case FE_TONEAREST: + if (fabs (xh) < 0.5 + || (fabs (xh) == 0.5 + && ((xh > 0.0 && xl < 0.0) + || (xh < 0.0 && xl > 0.0) + || (xl == 0.0 && (res & 1) == 0)))) + return res; + + if (xh < 0.0) + res -= 1; + else + res += 1; + break; + + case FE_TOWARDZERO: + if (res > 0 && (xh < 0.0 || (xh == 0.0 && xl < 0.0))) + res -= 1; + else if (res < 0 && (xh > 0.0 || (xh == 0.0 && xl > 0.0))) + res += 1; + return res; + break; + + case FE_UPWARD: + if (xh > 0.0 || (xh == 0.0 && xl > 0.0)) + res += 1; + break; + + case FE_DOWNWARD: + if (xh < 0.0 || (xh == 0.0 && xl < 0.0)) + res -= 1; + break; } - lowint = low; - result = high; - result += lowint; + + if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0)) + goto overflow; + + return res; } else - result = u.dd[0]; + { + if (xh > 0.0) + hi = __LONG_LONG_MAX__; + else if (xh < 0.0) + hi = -__LONG_LONG_MAX__ - 1; + else + /* Nan */ + hi = 0; + } - return result; +overflow: +#ifdef FE_INVALID + feraiseexcept (FE_INVALID); +#endif + return hi; } long_double_symbol (libm, __llrintl, llrintl); diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c index 567e7ecc07..103529d5a1 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c @@ -22,12 +22,11 @@ when it's coded in C. */ #include <math.h> -#include <fenv.h> +#include <fenv_libc.h> #include <math_ldbl_opt.h> #include <float.h> #include <ieee754.h> - #ifdef __STDC__ long long __llroundl (long double x) @@ -37,92 +36,95 @@ __llroundl (x) long double x; #endif { - static const double TWO52 = 4503599627370496.0; - static const double HALF = 0.5; - int mode = fegetround(); - union ibm_extended_long_double u; - long long result = __LONG_LONG_MAX__; - - u.d = x; - - if (fabs (u.dd[0]) < TWO52) - { - fesetround(FE_TOWARDZERO); - if (u.dd[0] > 0.0) + double xh, xl; + long long res, hi, lo; + + ldbl_unpack (x, &xh, &xl); + + /* Limit the range of values handled by the conversion to long long. + We do this because we aren't sure whether that conversion properly + raises FE_INVALID. */ + if (__builtin_expect + ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1) +#if !defined (FE_INVALID) + || 1 +#endif + ) + { + if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0)) { - u.dd[0] += HALF; - u.dd[0] += TWO52; - u.dd[0] -= TWO52; + /* When XH is 9223372036854775808.0, converting to long long will + overflow, resulting in an invalid operation. However, XL might + be negative and of sufficient magnitude that the overall long + double is in fact in range. Avoid raising an exception. In any + case we need to convert this value specially, because + the converted value is not exactly represented as a double + thus subtracting HI from XH suffers rounding error. */ + hi = __LONG_LONG_MAX__; + xh = 1.0; } - else if (u.dd[0] < 0.0) + else { - u.dd[0] = TWO52 - (u.dd[0] - HALF); - u.dd[0] = -(u.dd[0] - TWO52); + hi = (long long) xh; + xh -= hi; } - fesetround(mode); - result = u.dd[0]; - } - else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) - { - double high, low; - long long lowint; - /* In this case we have to round the low double and handle any - adjustment to the high double that may be caused by rounding - (up). This is complicated by the fact that the high double - may already be rounded and the low double may have the - opposite sign to compensate. */ - if (u.dd[0] > 0.0) + ldbl_canonicalize (&xh, &xl); + + lo = (long long) xh; + + /* Peg at max/min values, assuming that the above conversions do so. + Strictly speaking, we can return anything for values that overflow, + but this is more useful. */ + res = hi + lo; + + /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */ + if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0)) + goto overflow; + + xh -= lo; + ldbl_canonicalize (&xh, &xl); + + hi = res; + if (xh > 0.5) + { + res += 1; + } + else if (xh == 0.5) { - if (u.dd[1] > 0.0) - { - /* If the high/low doubles are the same sign then simply - round the low double. */ - high = u.dd[0]; - low = u.dd[1]; - } - else if (u.dd[1] < 0.0) - { - /* Else the high double is pre rounded and we need to - adjust for that. */ - high = nextafter (u.dd[0], 0.0); - low = u.dd[1] + (u.dd[0] - high); - } - fesetround(FE_TOWARDZERO); - low += HALF; - low += TWO52; - low -= TWO52; + if (xl > 0.0 || (xl == 0.0 && res >= 0)) + res += 1; } - else if (u.dd[0] < 0.0) + else if (-xh > 0.5) { - if (u.dd[1] < 0.0) - { - /* If the high/low doubles are the same sign then simply - round the low double. */ - high = u.dd[0]; - low = u.dd[1]; - } - else if (u.dd[1] > 0.0) - { - /* Else the high double is pre rounded and we need to - adjust for that. */ - high = nextafter (u.dd[0], 0.0); - low = u.dd[1] + (u.dd[0] - high); - } - fesetround(FE_TOWARDZERO); - low -= HALF; - low = TWO52 - low; - low = -(low - TWO52); + res -= 1; } - fesetround(mode); - lowint = low; - result = high; - result += lowint; + else if (-xh == 0.5) + { + if (xl < 0.0 || (xl == 0.0 && res <= 0)) + res -= 1; + } + + if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0)) + goto overflow; + + return res; } else - { - result = u.dd[0]; - } - return result; + { + if (xh > 0.0) + hi = __LONG_LONG_MAX__; + else if (xh < 0.0) + hi = -__LONG_LONG_MAX__ - 1; + else + /* Nan */ + hi = 0; + } + +overflow: +#ifdef FE_INVALID + feraiseexcept (FE_INVALID); +#endif + return hi; } long_double_symbol (libm, __llroundl, llroundl); diff --git a/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/sysdeps/powerpc/powerpc32/fpu/fprsave.S index 597c3e611f..c05178775d 100644 --- a/sysdeps/powerpc/powerpc32/fpu/fprsave.S +++ b/sysdeps/powerpc/powerpc32/fpu/fprsave.S @@ -27,68 +27,86 @@ ENTRY(_savefpr_all) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_14) C_TEXT(_savef14): C_TEXT(_savefpr_14): stfd fp14,-144(r1) + cfi_offset(fp14,-144) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef15) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_15) C_TEXT(_savef15): C_TEXT(_savefpr_15): stfd fp15,-136(r1) + cfi_offset(fp15,-136) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef16) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_16) C_TEXT(_savef16): C_TEXT(_savefpr_16): stfd fp16,-128(r1) + cfi_offset(fp16,-128) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef17) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_17) C_TEXT(_savef17): C_TEXT(_savefpr_17): stfd fp17,-120(r1) + cfi_offset(fp17,-120) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef18) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_18) C_TEXT(_savef18): C_TEXT(_savefpr_18): stfd fp18,-112(r1) + cfi_offset(fp18,-112) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef19) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_19) C_TEXT(_savef19): C_TEXT(_savefpr_19): stfd fp19,-104(r1) + cfi_offset(fp19,-104) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef20) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_20) C_TEXT(_savef20): C_TEXT(_savefpr_20): stfd fp20,-96(r1) + cfi_offset(fp20,-96) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef21) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_21) C_TEXT(_savef21): C_TEXT(_savefpr_21): stfd fp21,-88(r1) + cfi_offset(fp21,-88) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef22) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_22) C_TEXT(_savef22): C_TEXT(_savefpr_22): stfd fp22,-80(r1) + cfi_offset(fp22,-80) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef23) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_23) C_TEXT(_savef23): C_TEXT(_savefpr_23): stfd fp23,-72(r1) + cfi_offset(fp23,-72) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef24) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_24) C_TEXT(_savef24): C_TEXT(_savefpr_24): stfd fp24,-64(r1) + cfi_offset(fp24,-64) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef25) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_25) C_TEXT(_savef25): C_TEXT(_savefpr_25): stfd fp25,-56(r1) + cfi_offset(fp25,-56) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef26) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_26) C_TEXT(_savef26): C_TEXT(_savefpr_26): stfd fp26,-48(r1) + cfi_offset(fp26,-48) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef27) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_27) C_TEXT(_savef27): C_TEXT(_savefpr_27): stfd fp27,-40(r1) + cfi_offset(fp27,-40) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef28) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_28) C_TEXT(_savef28): C_TEXT(_savefpr_28): stfd fp28,-32(r1) + cfi_offset(fp28,-32) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef29) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_29) C_TEXT(_savef29): C_TEXT(_savefpr_29): stfd fp29,-24(r1) #save f29 stfd fp30,-16(r1) #save f30 stfd fp31,-8(r1) #save f31 + cfi_offset(fp29,-24) + cfi_offset(fp30,-16) + cfi_offset(fp31,-8) stw r0,8(r1) #save LR in callers frame blr #return END (_savefpr_all) diff --git a/sysdeps/powerpc/powerpc32/gprsave0.S b/sysdeps/powerpc/powerpc32/gprsave0.S index 8b81647dd7..c74272b56d 100644 --- a/sysdeps/powerpc/powerpc32/gprsave0.S +++ b/sysdeps/powerpc/powerpc32/gprsave0.S @@ -30,40 +30,59 @@ ENTRY(_savegpr0_all) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_13) C_TEXT(_savegpr0_13): stw r13,-76(r1) + cfi_offset(r13,-76) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_14) C_TEXT(_savegpr0_14): stw r14,-72(r1) + cfi_offset(r14,-72) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_15) C_TEXT(_savegpr0_15): stw r15,-68(r1) + cfi_offset(r15,-68) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_16) C_TEXT(_savegpr0_16): stw r16,-64(r1) + cfi_offset(r16,-64) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_17) C_TEXT(_savegpr0_17): stw r17,-60(r1) + cfi_offset(r17,-60) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_18) C_TEXT(_savegpr0_18): stw r18,-56(r1) + cfi_offset(r18,-56) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_19) C_TEXT(_savegpr0_19): stw r19,-52(r1) + cfi_offset(r19,-52) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_20) C_TEXT(_savegpr0_20): stw r20,-48(r1) + cfi_offset(r20,-48) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_21) C_TEXT(_savegpr0_21): stw r21,-44(r1) + cfi_offset(r21,-44) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_22) C_TEXT(_savegpr0_22): stw r22,-40(r1) + cfi_offset(r22,-40) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_23) C_TEXT(_savegpr0_23): stw r23,-36(r1) + cfi_offset(r23,-36) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_24) C_TEXT(_savegpr0_24): stw r24,-32(r1) + cfi_offset(r24,-32) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_25) C_TEXT(_savegpr0_25): stw r25,-28(r1) + cfi_offset(r25,-28) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_26) C_TEXT(_savegpr0_26): stw r26,-24(r1) + cfi_offset(r26,-24) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_27) C_TEXT(_savegpr0_27): stw r27,-20(r1) + cfi_offset(r27,-20) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_28) C_TEXT(_savegpr0_28): stw r28,-16(r1) + cfi_offset(r28,-16) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_29) C_TEXT(_savegpr0_29): stw r29,-12(r1) #save r29 stw r30,-8(r1) #save r30 stw r31,-4(r1) #save r31 + cfi_offset(r29,-12) + cfi_offset(r30,-8) + cfi_offset(r31,-4) stw r0,8(r1) #save LR in callers frame blr #return END (_savegpr0_all) diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S index c5afe5a3fa..9ca394dda2 100644 --- a/sysdeps/powerpc/powerpc64/dl-trampoline.S +++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S @@ -176,7 +176,9 @@ EALIGN(_dl_profile_resolve, 4, 0) /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we need to call _dl_call_pltexit. */ std r31,-8(r1) + cfi_offset(r31,-8) std r30,-16(r1) + cfi_offset(r30,-16) /* We need to save the registers used to pass parameters, ie. r3 thru r10; the registers are saved in a stack frame. */ stdu r1,-FRAME_SIZE(r1) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S b/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S deleted file mode 100644 index aa487775d4..0000000000 --- a/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S +++ /dev/null @@ -1,94 +0,0 @@ -/* Round long double to long int. - IBM extended format long double version. - Copyright (C) 2004,2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <sysdep.h> -#include <math_ldbl_opt.h> - - .section ".toc","aw" -.LC0: /* 2**52 */ - .tc FD_43300000_0[TC],0x4330000000000000 -.LC1: /* 2**63 */ - .tc FD_43E00000_0[TC],0x43e0000000000000 - .section ".text" - -/* long long int[r3] __llrintl (long double x[fp1,fp2]) */ -ENTRY (__llrintl) - lfd fp13,.LC0@toc(2) - lfd fp10,.LC1@toc(2) - fabs fp0,fp1 - fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ - fcmpu cr6,fp0,fp10 /* if (fabs(x) > TWO63) */ - beq- cr6,.L2 - fctid fp11,fp1 /* must delay this opperation to here */ - fctid fp12,fp2 /* and avoid setting "invalid operation". */ - li r0,0 - stfd fp11,-16(r1) - bgt- cr6,.L9 /* if > TWO63 return "invalid operation". */ - ble+ cr7,.L9 /* If < TWO52 only thy high double is used. */ - stfd fp12,-8(r1) - nop /* Insure the following load is in a different dispatch group */ - nop /* to avoid pipe stall on POWER4&5. */ - nop -.L8: - ld r0,-8(r1) -.L9: - ld r3,-16(r1) - add r3,r3,r0 - blr - -/* The high double is >= TWO63 so it looks like we are "out of range". - But this may be caused by rounding of the high double and the - negative low double may bring it back into range. So we need to - de-round the high double and invert the low double without changing - the effective long double value. To do this we compute a special - value (tau) that we can subtract from the high double and add to - the low double before conversion. The resulting integers can be - summed to get the total value. - - tau = floor(x_high/TWO52); - x0 = x_high - tau; - x1 = x_low + tau; */ -.L2: - fdiv fp8,fp1,fp13 /* x_high/TWO52 */ - fctidz fp0,fp8 - fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ - fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ - fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ - fctid fp11,fp3 - fctid fp12,fp4 - stfd fp11,-16(r1) - stfd fp12,-8(r1) - nop /* Insure the following load is in a different dispatch group */ - nop /* to avoid pipe stall on POWER4&5. */ - nop - ld r3,-16(r1) - ld r0,-8(r1) - addo. r3,r3,r0 - bnslr+ cr0 /* if the sum does not overflow, return. */ - fctid fp11,fp1 /* Otherwise we want to set "invalid operation". */ - li r0,0 - stfd fp11,-16(r1) - b .L9 - -END (__llrintl) - -strong_alias (__llrintl, __lrintl) -long_double_symbol (libm, __llrintl, llrintl) -long_double_symbol (libm, __lrintl, lrintl) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S b/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S deleted file mode 100644 index 29eca11093..0000000000 --- a/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S +++ /dev/null @@ -1,167 +0,0 @@ -/* llroundl function. - IBM extended format long double version. - Copyright (C) 2004, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <sysdep.h> -#include <math_ldbl_opt.h> - - .section ".toc","aw" -.LC0: /* 0.0 */ - .tc FD_00000000_0[TC],0x0000000000000000 -.LC1: /* 0.5 */ - .tc FD_3fe00000_0[TC],0x3fe0000000000000 -.LC2: /* 2**52 */ - .tc FD_43300000_0[TC],0x4330000000000000 -.LC3: /* 2**63 */ - .tc FD_43E00000_0[TC],0x43e0000000000000 - .section ".text" - -/* long long [r3] llround (long double x [fp1,fp2]) - IEEE 1003.1 llroundl function. IEEE specifies "round to the nearest - integer value, rounding halfway cases away from zero, regardless of - the current rounding mode." However PowerPC Architecture defines - "round to Nearest" as "Choose the best approximation. In case of a - tie, choose the one that is even (least significant bit o).". - So we can't use the PowerPC "round to Nearest" mode. Instead we set - "round toward Zero" mode and round by adding +-0.5 before rounding - toward zero. The "Floating Convert To Integer Doubleword with round - toward zero" instruction handles the conversion including the - overflow cases and signalling "Invalid Operation". - - PowerPC64 long double uses the IBM extended format which is - represented two 64-floating point double values. The values are - non-overlapping giving an effective precision of 106 bits. The first - double contains the high order bits of mantisa and is always rounded - to represent a normal rounding of long double to double. Since the - long double value is sum of the high and low values, the low double - normally has the opposite sign to compensate for the this rounding. - - For long double there is 4 cases: - 1) |x| < 2**52, all the integer bits are in the high double. - Round and convert the high double to long long. - 2) 2**52 <= |x|< 2**63, Still fits but need bits from both doubles. - Round the low double, convert both, then sum the long long values. - 3) |x| == 2**63, Looks like an overflow but may not be due to rounding - of the high double. - See the description following lable L2. - 4) |x| > 2**63, This will overflow the 64-bit signed integer. - Treat like case #1. The fctidz instruction will generate the - appropriate and signal "invalid operation". - - */ - -ENTRY (__llroundl) - mffs fp7 /* Save current FPU rounding mode. */ - fabs fp0,fp1 - lfd fp13,.LC2@toc(2) /* 2**52 */ - lfd fp12,.LC3@toc(2) /* 2**63 */ - lfd fp11,.LC0@toc(2) /* 0.0 */ - lfd fp10,.LC1@toc(2) /* 0.5 */ - fabs fp9,fp2 - fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ - fcmpu cr6,fp1,fp11 /* if (x > 0.0) */ - bnl- cr7,.L2 - mtfsfi 7,1 /* Set rounding mode toward 0. */ - ble- cr6,.L1 - fadd fp9,fp1,fp10 /* x+= 0.5; */ - b .L0 -.L1: - fsub fp9,fp1,fp10 /* x-= 0.5; */ -.L0: - fctid fp0,fp9 - stfd fp0,-16(r1) - mtfsf 0x01,fp7 /* restore previous rounding mode. */ - nop /* Insure the following load is in a different dispatch group */ - nop /* to avoid pipe stall on POWER4&5. */ - nop - ld r3,-16(r1) - blr - -/* The high double is > TWO52 so we need to round the low double and - perhaps the high double. In this case we have to round the low - double and handle any adjustment to the high double that may be - caused by rounding (up). This is complicated by the fact that the - high double may already be rounded and the low double may have the - opposite sign to compensate.This gets a bit tricky so we use the - following algorithm: - - tau = trunc(x_high/TWO52); - x0 = x_high - tau; - x1 = x_low + tau; - r1 = round(x1); - y_high = x0 + r1; - y_low = x0 - y_high + r1; - return y; */ -.L2: - fcmpu cr7,fp0,fp12 /* if (|x_high| > TWO63) */ - fcmpu cr0,fp9,fp11 /* || (|x_low| == 0.0) */ - fmr fp9,fp1 - fcmpu cr5,fp2,fp11 /* if (x_low > 0.0) */ - bgt- cr7,.L0 /* return llround(x); */ - mtfsfi 7,1 /* Set rounding mode toward 0. */ - fdiv fp8,fp1,fp13 /* x_high/TWO52 */ - - bng- cr6,.L6 /* if (x > 0.0) */ - fctidz fp0,fp8 - fcfid fp8,fp0 /* tau = trunc(x_high/TWO52); */ - bng cr5,.L4 /* if (x_low > 0.0) */ - fmr fp3,fp1 - fmr fp4,fp2 - b .L5 -.L4: /* if (x_low < 0.0) */ - fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ - fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ -.L5: - fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */ - b .L9 -.L6: /* if (x < 0.0) */ - fctidz fp0,fp8 - fcfid fp8,fp0 /* tau = trunc(x_high/TWO52); */ - bnl cr5,.L7 /* if (x_low < 0.0) */ - fmr fp3,fp1 - fmr fp4,fp2 - b .L8 -.L7: /* if (x_low > 0.0) */ - fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ - fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ -.L8: - fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */ -.L9: - fctid. fp11,fp3 - fctid fp12,fp5 - stfd fp11,-16(r1) - stfd fp12,-8(r1) - mtfsf 0x01,fp7 /* restore previous rounding mode. */ - nop /* Insure the following load is in a different dispatch group */ - nop /* to avoid pipe stall on POWER4&5. */ - nop - ld r3,-16(r1) - bunlr cr1 /* if not overflow, return. */ - ld r0,-8(r1) - addo. r3,r3,r0 - bnslr cr0 - fmr fp9,fp12 - bng cr6,.L0 - fneg fp9,fp12 - b .L0 -END (__llroundl) - -strong_alias (__llroundl, __lroundl) -long_double_symbol (libm, __llroundl, llroundl) -long_double_symbol (libm, __lroundl, lroundl) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S b/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S deleted file mode 100644 index 6c82d2e222..0000000000 --- a/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S +++ /dev/null @@ -1,2 +0,0 @@ -/* __lrintl is in s_llrintl.c */ -/* __lrintl is in s_llrintl.c */ diff --git a/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S b/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S deleted file mode 100644 index b24dfd8ded..0000000000 --- a/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S +++ /dev/null @@ -1,2 +0,0 @@ -/* __lroundl is in s_llroundl.S */ -/* __lroundl is in s_llroundl.S */ diff --git a/sysdeps/powerpc/powerpc64/memcpy.S b/sysdeps/powerpc/powerpc64/memcpy.S index 9df5bb42b6..f395de9066 100644 --- a/sysdeps/powerpc/powerpc64/memcpy.S +++ b/sysdeps/powerpc/powerpc64/memcpy.S @@ -1,5 +1,5 @@ /* Optimized memcpy implementation for PowerPC64. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2006 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 @@ -43,6 +43,7 @@ EALIGN (BP_SYM (memcpy), 5, 0) neg 0,3 std 3,-16(1) std 31,-8(1) + cfi_offset(31,-8) andi. 11,3,7 /* check alignement of dst. */ clrldi 0,0,61 /* Number of bytes until the 1st doubleword of dst. */ clrldi 10,4,61 /* check alignement of src. */ diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h index 707a4b0a52..ef553f7270 100644 --- a/sysdeps/sparc/sparc32/bits/atomic.h +++ b/sysdeps/sparc/sparc32/bits/atomic.h @@ -122,7 +122,7 @@ volatile unsigned char __sparc32_atomic_locks[64] __asm __volatile (".word 0xcde05005" \ : "+r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (__acev_oldval), "m" (*__acev_mem), \ - "r" (__acev_mem)); \ + "r" (__acev_mem) : "memory"); \ __acev_tmp; }) #endif diff --git a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h index 36959a9926..7b9d61d468 100644 --- a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h +++ b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h @@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t; __asm __volatile ("cas [%4], %2, %0" \ : "=r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval)); \ + "0" (newval) : "memory"); \ __acev_tmp; }) /* This can be implemented if needed. */ @@ -74,7 +74,7 @@ typedef uintmax_t uatomic_max_t; if (sizeof (*(mem)) == 4) \ __asm ("swap %0, %1" \ : "=m" (*__memp), "=r" (__oldval) \ - : "m" (*__memp), "1" (__value)); \ + : "m" (*__memp), "1" (__value) : "memory"); \ else \ abort (); \ __oldval; }) diff --git a/sysdeps/sparc/sparc64/bits/atomic.h b/sysdeps/sparc/sparc64/bits/atomic.h index 2fb377810e..d0a64afce8 100644 --- a/sysdeps/sparc/sparc64/bits/atomic.h +++ b/sysdeps/sparc/sparc64/bits/atomic.h @@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t; __asm __volatile ("cas [%4], %2, %0" \ : "=r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval)); \ + "0" (newval) : "memory"); \ __acev_tmp; }) #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ @@ -69,7 +69,7 @@ typedef uintmax_t uatomic_max_t; __asm __volatile ("casx [%4], %2, %0" \ : "=r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" ((long) (oldval)), "m" (*__acev_mem), \ - "r" (__acev_mem), "0" ((long) (newval))); \ + "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \ __acev_tmp; }) #define atomic_exchange_acq(mem, newvalue) \ @@ -80,7 +80,7 @@ typedef uintmax_t uatomic_max_t; if (sizeof (*(mem)) == 4) \ __asm ("swap %0, %1" \ : "=m" (*__memp), "=r" (__oldval) \ - : "m" (*__memp), "1" (__value)); \ + : "m" (*__memp), "1" (__value) : "memory"); \ else \ { \ __val = *__memp; \ diff --git a/sysdeps/unix/sysv/linux/alpha/getcontext.S b/sysdeps/unix/sysv/linux/alpha/getcontext.S index bf9820ac73..f010f337e6 100644 --- a/sysdeps/unix/sysv/linux/alpha/getcontext.S +++ b/sysdeps/unix/sysv/linux/alpha/getcontext.S @@ -1,5 +1,5 @@ /* Save current context. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -57,6 +57,8 @@ weak_alias (__getcontext, getcontext) __getcontext_x: cfi_register (64, 0) + .set noat + /* Return value of getcontext. $0 is the only register whose value is not preserved. */ stq $31, UC_SIGCTX+SC_REGS($16) diff --git a/sysdeps/unix/sysv/linux/bits/poll.h b/sysdeps/unix/sysv/linux/bits/poll.h index dccb8b6665..d7996b46c5 100644 --- a/sysdeps/unix/sysv/linux/bits/poll.h +++ b/sysdeps/unix/sysv/linux/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2006 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 @@ -36,8 +36,10 @@ #endif #ifdef __USE_GNU -/* This is an extension for Linux. */ +/* These are extensions for Linux. */ # define POLLMSG 0x400 +# define POLLREMOVE 0x1000 +# define POLLRDHUP 0x2000 #endif /* Event types always implicitly polled for. These bits need not be set in diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 9f3f3965f4..37d25b1a5c 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -105,10 +105,10 @@ # define __ASSUME_STAT64_SYSCALL 1 #endif -/* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64 +/* On sparc the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64 syscalls were introduced in 2.3.35. */ #if __LINUX_KERNEL_VERSION >= 131875 \ - && ((defined __sparc__ && !defined __arch64__) || defined __arm__) + && (defined __sparc__ && !defined __arch64__) # define __ASSUME_TRUNCATE64_SYSCALL 1 # define __ASSUME_MMAP2_SYSCALL 1 # define __ASSUME_STAT64_SYSCALL 1 @@ -191,7 +191,7 @@ don't know when it got introduced). But PowerPC64 does not support separate FCNTL64 call, FCNTL is already 64-bit */ #if __LINUX_KERNEL_VERSION >= 132100 \ - && (defined __arm__ || defined __powerpc__ || defined __sh__) \ + && (defined __powerpc__ || defined __sh__) \ && !defined __powerpc64__ # define __ASSUME_FCNTL64 1 #endif @@ -260,24 +260,10 @@ #endif /* The vfork syscall on x86 and arm was definitely available in 2.4. */ -#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __arm__) +#if __LINUX_KERNEL_VERSION >= 132097 && defined __i386__ # define __ASSUME_VFORK_SYSCALL 1 #endif -/* There are an infinite number of PA-RISC kernel versions numbered - 2.4.0. But they've not really been released as such. We require - and expect the final version here. */ -#ifdef __hppa__ -# define __ASSUME_32BITUIDS 1 -# define __ASSUME_TRUNCATE64_SYSCALL 1 -# define __ASSUME_MMAP2_SYSCALL 1 -# define __ASSUME_STAT64_SYSCALL 1 -# define __ASSUME_IPC64 1 -# define __ASSUME_ST_INO_64_BIT 1 -# define __ASSUME_FCNTL64 1 -# define __ASSUME_GETDENTS64_SYSCALL 1 -#endif - /* Alpha switched to a 64-bit timeval sometime before 2.2.0. */ #if __LINUX_KERNEL_VERSION >= 131584 && defined __alpha__ # define __ASSUME_TIMEVAL64 1 @@ -296,15 +282,6 @@ # define __ASSUME_CLONE_THREAD_FLAGS 1 #endif -/* These features were surely available with 2.4.12. */ -#if __LINUX_KERNEL_VERSION >= 132108 && defined __mc68000__ -# define __ASSUME_MMAP2_SYSCALL 1 -# define __ASSUME_TRUNCATE64_SYSCALL 1 -# define __ASSUME_STAT64_SYSCALL 1 -# define __ASSUME_FCNTL64 1 -# define __ASSUME_VFORK_SYSCALL 1 -#endif - /* Beginning with 2.5.63 support for realtime and monotonic clocks and timers based on them is available. */ #if __LINUX_KERNEL_VERSION >= 132415 @@ -359,7 +336,7 @@ /* The utimes syscall has been available for some architectures forever. For x86 it was introduced after 2.5.75, for x86-64, ppc, and ppc64 it was introduced in 2.6.0-test3. */ -#if defined __alpha__ || defined __ia64__ || defined __hppa__ \ +#if defined __alpha__ || defined __ia64__ \ || defined __sparc__ \ || (__LINUX_KERNEL_VERSION > 132427 && defined __i386__) \ || (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) \ @@ -468,3 +445,9 @@ && (defined __i386__ || defined __x86_64__) # define __ASSUME_ATFCTS 1 #endif + +/* Support for inter-process robust mutexes was added in 2.6.17. */ +#if __LINUX_KERNEL_VERSION >= 0x020611 \ + && (defined __i386__ || defined __x86_64__) +# define __ASSUME_SET_ROBUST_LIST 1 +#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S index 1a5251d100..40a7a24f19 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S @@ -45,6 +45,7 @@ ENTRY(__CONTEXT_FUNC_NAME) stw r0,20(r1) cfi_offset (lr, _FRAME_LR_SAVE) stw r31,12(r1) + cfi_offset(r31,-4) lwz r31,_UC_REGS_PTR(r3) /* diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S index a0f018ba41..366206d286 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S @@ -52,8 +52,12 @@ ENTRY (BP_SYM (__clone)) std r29,56(r1) std r30,64(r1) std r31,72(r1) + cfi_offset(r29,-56) + cfi_offset(r30,-64) + cfi_offset(r31,-72) #ifdef RESET_PID std r28,48(r1) + cfi_offset(r28,-48) #endif /* Set up stack frame for child. */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S index 98b49ba1dc..8d7c959ff9 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S @@ -144,6 +144,7 @@ ENTRY(__novec_getcontext) std r0,FRAME_LR_SAVE(r1) cfi_offset (lr, FRAME_LR_SAVE) stdu r1,-128(r1) + cfi_adjust_cfa_offset(128) li r3,ENOSYS bl JUMPTARGET(__syscall_error) nop diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S index 68fec9d2aa..48e9af363d 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S @@ -33,6 +33,7 @@ ENTRY(__novec_setcontext) #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL mflr r0 std r31,-8(1) + cfi_offset(r31,-8) std r0,FRAME_LR_SAVE(r1) cfi_offset (lr, FRAME_LR_SAVE) stdu r1,-128(r1) @@ -169,7 +170,9 @@ L(nv_do_sigret): /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */ mflr r0 std r0,FRAME_LR_SAVE(r1) + cfi_offset(lr,FRAME_LR_SAVE) stdu r1,-128(r1) + cfi_adjust_cfa_offset(128) li r3,ENOSYS bl JUMPTARGET(__syscall_error) nop @@ -201,6 +204,7 @@ ENTRY(__setcontext) #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL mflr r0 std r31,-8(1) + cfi_offset(r31,-8) std r0,FRAME_LR_SAVE(r1) cfi_offset (lr, FRAME_LR_SAVE) stdu r1,-128(r1) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S index 5a128606ad..936d641b6b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S @@ -35,6 +35,7 @@ ENTRY(__novec_swapcontext) std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3) mflr r0 std r31,-8(1) + cfi_offset(r31,-8) std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) std r0,FRAME_LR_SAVE(r1) cfi_offset (lr, FRAME_LR_SAVE) @@ -264,6 +265,7 @@ L(nv_do_sigret): /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */ mflr r0 std r0,FRAME_LR_SAVE(r1) + cfi_offset(lr,FRAME_LR_SAVE) stdu r1,-128(r1) li r3,ENOSYS bl JUMPTARGET(__syscall_error) @@ -298,11 +300,14 @@ ENTRY(__swapcontext) std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3) mflr r0 std r31,-8(1) + cfi_offset(r31,-8) std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) std r0,FRAME_LR_SAVE(r1) + cfi_offset (lr, FRAME_LR_SAVE) std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3) std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) stdu r1,-128(r1) + cfi_adjust_cfa_offset(128) std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3) std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3) std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3) diff --git a/sysdeps/unix/sysv/linux/sparc/bits/poll.h b/sysdeps/unix/sysv/linux/sparc/bits/poll.h index f7a7393154..53b94bc50e 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/poll.h +++ b/sysdeps/unix/sysv/linux/sparc/bits/poll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2001, 2006 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 @@ -35,6 +35,13 @@ # define POLLWRBAND 0x100 /* Priority data may be written. */ #endif +#ifdef __USE_GNU +/* These are extensions for Linux. */ +# define POLLMSG 0x200 +# define POLLREMOVE 0x400 +# define POLLRDHUP 0x800 +#endif + /* Event types always implicitly polled for. These bits need not be set in `events', but they will appear in `revents' to indicate the status of the file descriptor. */ diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h index 670dc79c4a..5dc7e19345 100644 --- a/wcsmbs/wchar.h +++ b/wcsmbs/wchar.h @@ -321,6 +321,7 @@ __END_NAMESPACE_C99 #ifdef __USE_EXTERN_INLINES /* Define inline function as optimization. */ +# ifndef __cplusplus /* We can use the BTOWC and WCTOB optimizations since we know that all locales must use ASCII encoding for the values in the ASCII range and because the wchar_t encoding is always ISO 10646. */ @@ -335,6 +336,7 @@ extern __inline int __NTH (wctob (wint_t __wc)) { return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f' ? (int) __wc : __wctob_alias (__wc)); } +# endif extern __inline size_t __NTH (mbrlen (__const char *__restrict __s, size_t __n, @@ -507,26 +509,30 @@ extern long double __wcstold_internal (__const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __group) __THROW; -#ifndef __wcstol_internal_defined +#if !defined __wcstol_internal_defined \ + && defined __OPTIMIZE__ && __GNUC__ >= 2 extern long int __wcstol_internal (__const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base, int __group) __THROW; # define __wcstol_internal_defined 1 #endif -#ifndef __wcstoul_internal_defined +#if !defined __wcstoul_internal_defined \ + && defined __OPTIMIZE__ && __GNUC__ >= 2 extern unsigned long int __wcstoul_internal (__const wchar_t *__restrict __npt, wchar_t **__restrict __endptr, int __base, int __group) __THROW; # define __wcstoul_internal_defined 1 #endif -#ifndef __wcstoll_internal_defined +#if !defined __wcstoll_internal_defined \ + && defined __OPTIMIZE__ && __GNUC__ >= 2 __extension__ extern long long int __wcstoll_internal (__const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base, int __group) __THROW; # define __wcstoll_internal_defined 1 #endif -#ifndef __wcstoull_internal_defined +#if !defined __wcstoull_internal_defined \ + && defined __OPTIMIZE__ && __GNUC__ >= 2 __extension__ extern unsigned long long int __wcstoull_internal (__const wchar_t * __restrict __nptr, |