diff options
Diffstat (limited to 'sysdeps')
91 files changed, 1287 insertions, 1371 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 29f500b2d0..88c357ea07 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. Alpha version. - Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson <rth@tamu.edu>. @@ -232,14 +232,14 @@ $fixup_stack: \n\ to one of the main executable's symbols, as for a COPY reloc. This is unused on Alpha. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD -# define elf_machine_type_class(type) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#define elf_machine_type_class(type) \ (((type) == R_ALPHA_JMP_SLOT \ || (type) == R_ALPHA_DTPMOD64 \ || (type) == R_ALPHA_DTPREL64 \ || (type) == R_ALPHA_TPREL64) * ELF_RTYPE_CLASS_PLT) #else -# define elf_machine_type_class(type) \ +#define elf_machine_type_class(type) \ (((type) == R_ALPHA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) #endif @@ -439,40 +439,40 @@ elf_machine_rela (struct link_map *map, memcpy (reloc_addr_arg, &sym_value, 8); } #endif -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) else if (r_type == R_ALPHA_DTPMOD64) { -# ifdef RTLD_BOOTSTRAP +#ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always index 1. */ *reloc_addr = 1; -# else +#else /* Get the information from the link map returned by the resolv function. */ if (sym_map != NULL) *reloc_addr = sym_map->l_tls_modid; -# endif +#endif } else if (r_type == R_ALPHA_DTPREL64) { -# ifndef RTLD_BOOTSTRAP +#ifndef RTLD_BOOTSTRAP /* During relocation all TLS symbols are defined and used. Therefore the offset is already correct. */ *reloc_addr = sym_raw_value; -# endif +#endif } else if (r_type == R_ALPHA_TPREL64) { -# ifdef RTLD_BOOTSTRAP +#ifdef RTLD_BOOTSTRAP *reloc_addr = sym_raw_value + map->l_tls_offset; -# else +#else if (sym_map) { CHECK_STATIC_TLS (map, sym_map); *reloc_addr = sym_raw_value + sym_map->l_tls_offset; } -# endif - } #endif + } +#endif /* USE_TLS */ else _dl_reloc_bad_type (map, r_type, 0); } diff --git a/sysdeps/alpha/libc-tls.c b/sysdeps/alpha/libc-tls.c index 7e02769171..24629e9aca 100644 --- a/sysdeps/alpha/libc-tls.c +++ b/sysdeps/alpha/libc-tls.c @@ -1,5 +1,5 @@ /* Thread-local storage handling in the ELF dynamic linker. Alpha version. - Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,6 +20,8 @@ #include <csu/libc-tls.c> #include <dl-tls.h> +#if USE_TLS + /* On Alpha, linker optimizations are not required, so __tls_get_addr can be called even in statically linked binaries. In this case module must be always 1 and PT_TLS segment exist in the binary, otherwise it @@ -31,3 +33,5 @@ __tls_get_addr (tls_index *ti) dtv_t *dtv = THREAD_DTV (); return (char *) dtv[1].pointer.val + ti->ti_offset; } + +#endif diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index dda91bb806..eee6141c6a 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1,5 +1,5 @@ /* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007 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 @@ -38,7 +38,6 @@ #include <bits/libc-lock.h> #include <hp-timing.h> #include <tls.h> -#include <rtld-lowlevel.h> __BEGIN_DECLS @@ -439,18 +438,23 @@ struct rtld_global EXTERN void (*_dl_rtld_unlock_recursive) (void *); #endif - /* Prevailing state of the stack, PF_X indicating it's executable. */ - EXTERN ElfW(Word) _dl_stack_flags; - /* If loading a shared object requires that we make the stack executable when it was not, we do it by calling this function. It returns an errno code or zero on success. */ EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function; - /* Highest dtv index currently needed. */ - EXTERN size_t _dl_tls_max_dtv_idx; + /* Prevailing state of the stack, PF_X indicating it's executable. */ + EXTERN ElfW(Word) _dl_stack_flags; + + /* Keep the conditional TLS members at the end so the layout of the + structure used by !USE_TLS code matches the prefix of the layout in + the USE_TLS rtld. Note that `struct link_map' is conditionally + defined as well, so _dl_rtld_map needs to be last before this. */ +#ifdef USE_TLS /* Flag signalling whether there are gaps in the module ID allocation. */ EXTERN bool _dl_tls_dtv_gaps; + /* Highest dtv index currently needed. */ + EXTERN size_t _dl_tls_max_dtv_idx; /* Information about the dtv slots. */ EXTERN struct dtv_slotinfo_list { @@ -474,10 +478,10 @@ struct rtld_global /* Number of additional entries in the slotinfo array of each slotinfo list element. A large number makes it almost certain take we never have to iterate beyond the first element in the slotinfo list. */ -#define TLS_SLOTINFO_SURPLUS (62) +# define TLS_SLOTINFO_SURPLUS (62) /* Number of additional slots in the dtv allocated. */ -#define DTV_SURPLUS (14) +# define DTV_SURPLUS (14) /* Initial dtv of the main thread, not allocated with normal malloc. */ EXTERN void *_dl_initial_dtv; @@ -485,18 +489,31 @@ struct rtld_global EXTERN size_t _dl_tls_generation; EXTERN void (*_dl_init_static_tls) (struct link_map *); +#endif + + EXTERN void (*_dl_wait_lookup_done) (void); + /* Scopes to free after next THREAD_GSCOPE_WAIT (). */ + EXTERN struct dl_scope_free_list + { + size_t count; + struct r_scope_elem **list[50]; + } *_dl_scope_free_list; #ifdef SHARED }; # define __rtld_global_attribute__ # ifdef IS_IN_rtld -# ifdef HAVE_SDATA_SECTION -# define __rtld_local_attribute__ \ +# ifdef HAVE_VISIBILITY_ATTRIBUTE +# ifdef HAVE_SDATA_SECTION +# define __rtld_local_attribute__ \ __attribute__ ((visibility ("hidden"), section (".sdata"))) -# undef __rtld_global_attribute__ -# define __rtld_global_attribute__ __attribute__ ((section (".sdata"))) +# undef __rtld_global_attribute__ +# define __rtld_global_attribute__ __attribute__ ((section (".sdata"))) +# else +# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) +# endif # else -# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) +# define __rtld_local_attribute__ # endif extern struct rtld_global _rtld_local __rtld_local_attribute__; # undef __rtld_local_attribute__ @@ -532,15 +549,15 @@ struct rtld_global_ro #define DL_DEBUG_HELP (1 << 9) #define DL_DEBUG_PRELINK (1 << 10) - /* Cached value of `getpagesize ()'. */ - EXTERN size_t _dl_pagesize; - /* OS version. */ EXTERN unsigned int _dl_osversion; /* Platform name. */ EXTERN const char *_dl_platform; EXTERN size_t _dl_platformlen; + /* Cached value of `getpagesize ()'. */ + EXTERN size_t _dl_pagesize; + /* Copy of the content of `_dl_main_searchlist' at startup time. */ EXTERN struct r_scope_elem _dl_initial_searchlist; @@ -569,9 +586,6 @@ struct rtld_global_ro /* Expected cache ID. */ EXTERN int _dl_correct_cache_id; - /* 0 if internal pointer values should not be guarded, 1 if they should. */ - EXTERN int _dl_pointer_guard; - /* Mask for hardware capabilities that are available. */ EXTERN uint64_t _dl_hwcap; @@ -655,10 +669,17 @@ struct rtld_global_ro /* List of auditing interfaces. */ struct audit_ifaces *_dl_audit; unsigned int _dl_naudit; + + /* 0 if internal pointer values should not be guarded, 1 if they should. */ + EXTERN int _dl_pointer_guard; }; # define __rtld_global_attribute__ # ifdef IS_IN_rtld -# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) +# ifdef HAVE_VISIBILITY_ATTRIBUTE +# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) +# else +# define __rtld_local_attribute__ +# endif extern struct rtld_global_ro _rtld_local_ro attribute_relro __rtld_local_attribute__; extern struct rtld_global_ro _rtld_global_ro @@ -1023,7 +1044,9 @@ rtld_hidden_proto (_dl_allocate_tls_init) extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function; rtld_hidden_proto (_dl_deallocate_tls) +#if defined USE_TLS extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden; +#endif /* Find origin of the executable. */ extern const char *_dl_get_origin (void) attribute_hidden; @@ -1046,6 +1069,11 @@ extern void *_dl_open (const char *name, int mode, const void *caller, Lmid_t nsid, int argc, char *argv[], char *env[]) attribute_hidden; +/* Free or queue for freeing scope OLD. If other threads might be + in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the + old scope, OLD can't be freed until no thread is using it. */ +extern int _dl_scope_free (struct r_scope_elem **old) attribute_hidden; + /* Add module to slot information data. */ extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden; @@ -1057,6 +1085,8 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid); but never touch anything. Return null if it's not allocated yet. */ extern void *_dl_tls_get_addr_soft (struct link_map *l) internal_function; +extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) + internal_function attribute_hidden; __END_DECLS diff --git a/sysdeps/generic/tls.h b/sysdeps/generic/tls.h index 06e41ad121..6a23ec05e1 100644 --- a/sysdeps/generic/tls.h +++ b/sysdeps/generic/tls.h @@ -1,5 +1,5 @@ /* Definition for thread-local data handling. Generic version. - Copyright (C) 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,6 +17,11 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +/* By default no TLS support is available. This is signaled by the + absence of the symbol USE_TLS. */ +#undef USE_TLS + + /* An architecture-specific version of this file has to defined a number of symbols: diff --git a/sysdeps/gnu/errlist-compat.awk b/sysdeps/gnu/errlist-compat.awk index 307c4d7020..ab67a18f64 100644 --- a/sysdeps/gnu/errlist-compat.awk +++ b/sysdeps/gnu/errlist-compat.awk @@ -1,5 +1,5 @@ # awk script to generate errlist-compat.c -# Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. +# Copyright (C) 2002, 2004 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -92,18 +92,16 @@ END { printf "# include <bits/wordsize.h>\n"; printf "extern const char *const __sys_errlist_%s[NERR];\n", old; printf "const int __sys_nerr_%s = %d;\n", old, n; - printf "declare_symbol_alias (__sys_errlist_%s, _sys_errlist_internal,", \ - old; - printf " object, __WORDSIZE/8*%d)\n", n; + printf "strong_alias (_sys_errlist_internal, __sys_errlist_%s)\n", old; + printf "declare_symbol (__sys_errlist_%s, object, __WORDSIZE/8*%d)\n", \ + old, n; printf "compat_symbol (libc, __sys_errlist_%s, sys_errlist, %s);\n", \ old, old; printf "compat_symbol (libc, __sys_nerr_%s, sys_nerr, %s);\n", old, old; printf "extern const char *const ___sys_errlist_%s[NERR];\n", old; printf "extern const int __sys_nerr_%s;\n", old; - printf "declare_symbol_alias (___sys_errlist_%s, _sys_errlist_internal,", \ - old; - printf " object, __WORDSIZE/8*%d)\n", n; + printf "strong_alias (__sys_errlist_%s, ___sys_errlist_%s)\n", old, old; printf "strong_alias (__sys_nerr_%s, ___sys_nerr_%s)\n", old, old; printf "compat_symbol (libc, ___sys_errlist_%s, _sys_errlist, %s);\n", \ old, old; diff --git a/sysdeps/gnu/netinet/tcp.h b/sysdeps/gnu/netinet/tcp.h index 2c04ec9b7f..87099ec14a 100644 --- a/sysdeps/gnu/netinet/tcp.h +++ b/sysdeps/gnu/netinet/tcp.h @@ -49,7 +49,6 @@ #define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ #define TCP_INFO 11 /* Information about this connection. */ #define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */ -#define TCP_CONGESTION 13 /* Congestion control algorithm. */ #ifdef __USE_MISC # include <sys/types.h> diff --git a/sysdeps/gnu/siglist.c b/sysdeps/gnu/siglist.c index 3005f867f0..cb1875f9eb 100644 --- a/sysdeps/gnu/siglist.c +++ b/sysdeps/gnu/siglist.c @@ -1,5 +1,5 @@ /* Define list of all signal numbers and their names. - Copyright (C) 1997-2000, 2002, 2003, 2006 Free Software Foundation, Inc. + Copyright (C) 1997-2000, 2002, 2003 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 @@ -40,30 +40,27 @@ const char *const __new_sys_sigabbrev[NSIG] = strong_alias (__new_sys_sigabbrev, _sys_sigabbrev_internal) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -declare_symbol_alias (__old_sys_siglist, __new_sys_siglist, object, - OLD_SIGLIST_SIZE * __WORDSIZE / 8) +strong_alias (_sys_siglist_internal, __old_sys_siglist) +declare_symbol (__old_sys_siglist, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8) -declare_symbol_alias (__old_sys_sigabbrev, __new_sys_sigabbrev, object, - OLD_SIGLIST_SIZE * __WORDSIZE / 8) - -declare_symbol_alias (_old_sys_siglist, __new_sys_siglist, object, - OLD_SIGLIST_SIZE * __WORDSIZE / 8) +strong_alias (_sys_sigabbrev_internal, __old_sys_sigabbrev) +declare_symbol (__old_sys_sigabbrev, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8) +strong_alias (__old_sys_siglist, _old_sys_siglist) compat_symbol (libc, __old_sys_siglist, _sys_siglist, GLIBC_2_0); compat_symbol (libc, _old_sys_siglist, sys_siglist, GLIBC_2_0); compat_symbol (libc, __old_sys_sigabbrev, sys_sigabbrev, GLIBC_2_0); #endif #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3) && defined OLD2_SIGLIST_SIZE -declare_symbol_alias (__old2_sys_siglist, __new_sys_siglist, object, - OLD2_SIGLIST_SIZE * __WORDSIZE / 8) - -declare_symbol_alias (__old2_sys_sigabbrev, __new_sys_sigabbrev, object, - OLD2_SIGLIST_SIZE * __WORDSIZE / 8) +strong_alias (_sys_siglist_internal, __old2_sys_siglist) +declare_symbol (__old2_sys_siglist, object, OLD2_SIGLIST_SIZE * __WORDSIZE / 8) -declare_symbol_alias (_old2_sys_siglist, __new_sys_siglist, object, - OLD2_SIGLIST_SIZE * __WORDSIZE / 8) +strong_alias (_sys_sigabbrev_internal, __old2_sys_sigabbrev) +declare_symbol (__old2_sys_sigabbrev, object, + OLD2_SIGLIST_SIZE * __WORDSIZE / 8) +strong_alias (__old2_sys_siglist, _old2_sys_siglist) compat_symbol (libc, __old2_sys_siglist, _sys_siglist, GLIBC_2_1); compat_symbol (libc, _old2_sys_siglist, sys_siglist, GLIBC_2_1); compat_symbol (libc, __old2_sys_sigabbrev, sys_sigabbrev, GLIBC_2_1); diff --git a/sysdeps/i386/bits/byteswap.h b/sysdeps/i386/bits/byteswap.h index bed27559c5..7f2ddc2dc5 100644 --- a/sysdeps/i386/bits/byteswap.h +++ b/sysdeps/i386/bits/byteswap.h @@ -1,5 +1,6 @@ /* Macros to swap the order of bytes in integer values. - Copyright (C) 1997,1998,2000,2002,2003,2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 2007 + 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 @@ -66,7 +67,8 @@ __bswap_16 (unsigned short int __bsx) `bswap' opcode. On i386 we have to use three instructions. */ # if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \ && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \ - && !defined __k6__ + && !defined __k6__ && !defined __nocona__ && !defined __core2__ \ + && !defined __geode__ && !defined __amdfam10__ # define __bswap_32(x) \ (__extension__ \ ({ register unsigned int __v, __x = (x); \ diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 04296d2a9a..df3edf5460 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. i386 version. - Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,7 +34,9 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr) } -#ifdef PI_STATIC_AND_HIDDEN +#if defined PI_STATIC_AND_HIDDEN \ + && defined HAVE_VISIBILITY_ATTRIBUTE && defined HAVE_HIDDEN \ + && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE /* Return the link-time address of _DYNAMIC. Conveniently, this is the first element of the GOT, a special entry that is never relocated. */ @@ -242,7 +244,7 @@ _dl_start_user:\n\ define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) # define elf_machine_type_class(type) \ ((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32 \ || (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32 \ @@ -350,7 +352,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, *reloc_addr = value; break; -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) case R_386_TLS_DTPMOD32: # ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module @@ -474,6 +476,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr); break; +# ifdef USE_TLS case R_386_TLS_DTPMOD32: /* Get the information from the link map returned by the resolv function. */ @@ -510,6 +513,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + reloc->r_addend; } break; +# endif /* use TLS */ case R_386_COPY: if (sym == NULL) /* This can happen in trace mode if an object could not be diff --git a/sysdeps/i386/fpu/e_log.S b/sysdeps/i386/fpu/e_log.S index 5604e638f5..ce55b72292 100644 --- a/sysdeps/i386/fpu/e_log.S +++ b/sysdeps/i386/fpu/e_log.S @@ -36,11 +36,15 @@ limit: .double 0.29 ENTRY(__ieee754_log) fldln2 // log(2) fldl 4(%esp) // x : log(2) + fxam + fnstsw #ifdef PIC LOAD_PIC_REG (dx) #endif fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + sahf + jc 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -54,4 +58,9 @@ ENTRY(__ieee754_log) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: jp 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_log) diff --git a/sysdeps/i386/fpu/e_logf.S b/sysdeps/i386/fpu/e_logf.S index 128bb2754c..cd4538b594 100644 --- a/sysdeps/i386/fpu/e_logf.S +++ b/sysdeps/i386/fpu/e_logf.S @@ -37,11 +37,15 @@ limit: .double 0.29 ENTRY(__ieee754_logf) fldln2 // log(2) flds 4(%esp) // x : log(2) + fxam + fnstsw #ifdef PIC LOAD_PIC_REG (dx) #endif fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + sahf + jc 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -55,4 +59,9 @@ ENTRY(__ieee754_logf) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: jp 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_logf) diff --git a/sysdeps/i386/fpu/e_logl.S b/sysdeps/i386/fpu/e_logl.S index 5023d3012f..551dcf1e46 100644 --- a/sysdeps/i386/fpu/e_logl.S +++ b/sysdeps/i386/fpu/e_logl.S @@ -37,11 +37,15 @@ limit: .double 0.29 ENTRY(__ieee754_logl) fldln2 // log(2) fldt 4(%esp) // x : log(2) + fxam + fnstsw #ifdef PIC LOAD_PIC_REG (dx) #endif fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + sahf + jc 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -55,4 +59,9 @@ ENTRY(__ieee754_logl) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: jp 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_logl) diff --git a/sysdeps/i386/fpu/e_pow.S b/sysdeps/i386/fpu/e_pow.S index c554ca4ecb..792f926902 100644 --- a/sysdeps/i386/fpu/e_pow.S +++ b/sysdeps/i386/fpu/e_pow.S @@ -1,5 +1,5 @@ /* ix87 specific implementation of pow function. - Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005 + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -161,10 +161,11 @@ ENTRY(__ieee754_pow) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 1.0 : x : y - fld %st(1) // x : 1.0 : x : y - fsub %st(1) // x-1 : 1.0 : x : y - fabs // |x-1| : 1.0 : x : y - fcompl MO(limit) // 1.0 : x : y + fldl MO(limit) // 0.29 : 1.0 : x : y + fld %st(2) // x : 0.29 : 1.0 : x : y + fsub %st(2) // x-1 : 0.29 : 1.0 : x : y + fabs // |x-1| : 0.29 : 1.0 : x : y + fucompp // 1.0 : x : y fnstsw fxch // x : 1.0 : y sahf @@ -197,9 +198,10 @@ ENTRY(__ieee754_pow) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldl 4(%esp) // x - fabs - fcompl MO(one) // < 1, == 1, or > 1 + fldl MO(one) // 1 + fldl 4(%esp) // x : 1 + fabs // abs(x) : 1 + fucompp // < 1, == 1, or > 1 fnstsw andb $0x45, %ah cmpb $0x45, %ah diff --git a/sysdeps/i386/fpu/e_powf.S b/sysdeps/i386/fpu/e_powf.S index c835b978b9..c91545418d 100644 --- a/sysdeps/i386/fpu/e_powf.S +++ b/sysdeps/i386/fpu/e_powf.S @@ -1,5 +1,5 @@ /* ix87 specific implementation of pow function. - Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005 + Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -155,10 +155,11 @@ ENTRY(__ieee754_powf) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 1.0 : x : y - fld %st(1) // x : 1.0 : x : y - fsub %st(1) // x-1 : 1.0 : x : y - fabs // |x-1| : 1.0 : x : y - fcompl MO(limit) // 1.0 : x : y + fldl MO(limit) // 0.29 : 1.0 : x : y + fld %st(2) // x : 0.29 : 1.0 : x : y + fsub %st(2) // x-1 : 0.29 : 1.0 : x : y + fabs // |x-1| : 0.29 : 1.0 : x : y + fucompp // 1.0 : x : y fnstsw fxch // x : 1.0 : y sahf @@ -191,9 +192,10 @@ ENTRY(__ieee754_powf) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - flds 4(%esp) // x - fabs - fcompl MO(one) // < 1, == 1, or > 1 + fldl MO(one) // 1 + flds 4(%esp) // x : 1 + fabs // abs(x) : 1 + fucompp // < 1, == 1, or > 1 fnstsw andb $0x45, %ah cmpb $0x45, %ah diff --git a/sysdeps/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S index 74f422816a..6215496207 100644 --- a/sysdeps/i386/fpu/e_powl.S +++ b/sysdeps/i386/fpu/e_powl.S @@ -1,5 +1,5 @@ /* ix87 specific implementation of pow function. - Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005 + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -161,10 +161,11 @@ ENTRY(__ieee754_powl) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 1.0 : x : y - fld %st(1) // x : 1.0 : x : y - fsub %st(1) // x-1 : 1.0 : x : y - fabs // |x-1| : 1.0 : x : y - fcompl MO(limit) // 1.0 : x : y + fldl MO(limit) // 0.29 : 1.0 : x : y + fld %st(2) // x : 0.29 : 1.0 : x : y + fsub %st(2) // x-1 : 0.29 : 1.0 : x : y + fabs // |x-1| : 0.29 : 1.0 : x : y + fucompp // 1.0 : x : y fnstsw fxch // x : 1.0 : y sahf @@ -210,9 +211,10 @@ ENTRY(__ieee754_powl) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldt 4(%esp) // x - fabs - fcompl MO(one) // < 1, == 1, or > 1 + fldl MO(one) // 1 + fldt 4(%esp) // x : 1 + fabs // abs(x) : 1 + fucompp // < 1, == 1, or > 1 fnstsw andb $0x45, %ah cmpb $0x45, %ah diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h new file mode 100644 index 0000000000..a426788ef1 --- /dev/null +++ b/sysdeps/i386/fpu/math_private.h @@ -0,0 +1,18 @@ +#ifndef _MATH_PRIVATE_H + +#define math_opt_barrier(x) \ +({ __typeof(x) __x; \ + __asm ("" : "=t" (__x) : "0" (x)); \ + __x; }) +#define math_force_eval(x) \ +do \ + { \ + if (sizeof (x) <= sizeof (double)) \ + __asm __volatile ("" : : "m" (x)); \ + else \ + __asm __volatile ("" : : "f" (x)); \ + } \ +while (0) + +#include <math/math_private.h> +#endif diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c index 5b617cb4e7..aef0a144e5 100644 --- a/sysdeps/i386/fpu/s_nextafterl.c +++ b/sysdeps/i386/fpu/s_nextafterl.c @@ -27,7 +27,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> #ifdef __STDC__ long double __nextafterl(long double x, long double y) @@ -52,9 +52,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if(x==y) return y; /* x=y, return y */ if((ix|hx|lx)==0) { /* x == 0 */ + long double u; SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(esx>=0) { /* x > 0 */ if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { @@ -109,12 +112,9 @@ static char rcsid[] = "$NetBSD: $"; } esy = esx&0x7fff; if(esy==0x7fff) return x+x; /* overflow */ - if(esy==0) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ - SET_LDOUBLE_WORDS(y,esx,hx,lx); - return y; - } + if(esy==0) { + long double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_LDOUBLE_WORDS(x,esx,hx,lx); return x; diff --git a/sysdeps/i386/fpu/s_nexttoward.c b/sysdeps/i386/fpu/s_nexttoward.c index 2bd768e448..9bd86a3724 100644 --- a/sysdeps/i386/fpu/s_nexttoward.c +++ b/sysdeps/i386/fpu/s_nexttoward.c @@ -27,7 +27,8 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> +#include <float.h> #ifdef __STDC__ double __nexttoward(double x, long double y) @@ -52,10 +53,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ - double x2; + double u; INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 @@ -85,16 +88,14 @@ static char rcsid[] = "$NetBSD: $"; hy = hx&0x7ff00000; if(hy>=0x7ff00000) { x = x+x; /* overflow */ - /* Force conversion to double. */ - asm ("" : "=m"(x) : "m"(x)); + if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) + /* Force conversion to double. */ + asm ("" : "+m"(x)); return x; } - if(hy<0x00100000) { /* underflow */ - double x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - INSERT_WORDS(x2,hx,lx); - return x2; - } + if(hy<0x00100000) { + double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } INSERT_WORDS(x,hx,lx); return x; diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c index 3fbe53c338..25f70e4f4d 100644 --- a/sysdeps/i386/fpu/s_nexttowardf.c +++ b/sysdeps/i386/fpu/s_nexttowardf.c @@ -19,7 +19,8 @@ static char rcsid[] = "$NetBSD: $"; #endif #include "math.h" -#include "math_private.h" +#include <math_private.h> +#include <float.h> #ifdef __STDC__ float __nexttowardf(float x, long double y) @@ -44,10 +45,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float x2; + float u; SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 @@ -69,16 +72,14 @@ static char rcsid[] = "$NetBSD: $"; hy = hx&0x7f800000; if(hy>=0x7f800000) { x = x+x; /* overflow */ - /* Force conversion to float. */ - asm ("" : "=m"(x) : "m"(x)); + if (FLT_EVAL_METHOD != 0) + /* Force conversion to float. */ + asm ("" : "+m"(x)); return x; } - if(hy<0x00800000) { /* underflow */ - float x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - SET_FLOAT_WORD(x2,hx); - return x2; - } + if(hy<0x00800000) { + float u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h index a27734c37e..c748761758 100644 --- a/sysdeps/i386/i486/bits/atomic.h +++ b/sysdeps/i386/i486/bits/atomic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -18,7 +18,6 @@ 02111-1307 USA. */ #include <stdint.h> -#include <tls.h> /* For tcbhead_t. */ typedef int8_t atomic8_t; @@ -77,40 +76,6 @@ typedef uintmax_t uatomic_max_t; : "r" (newval), "m" (*mem), "0" (oldval)); \ ret; }) - -#define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgb %b2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "q" (newval), "m" (*mem), "0" (oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) - -#define __arch_c_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgw %w2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "r" (newval), "m" (*mem), "0" (oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) - -#define __arch_c_compare_and_exchange_val_32_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgl %2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "r" (newval), "m" (*mem), "0" (oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) - /* XXX We do not really need 64-bit compare-and-exchange. At least not in the moment. Using it would mean causing portability problems since not many other 32-bit architectures have support for @@ -120,8 +85,6 @@ typedef uintmax_t uatomic_max_t; #if 1 # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); }) -# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); }) #else # ifdef __PIC__ # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ @@ -137,24 +100,6 @@ typedef uintmax_t uatomic_max_t; & 0xffffffff), \ "d" (((unsigned long long int) (oldval)) >> 32)); \ ret; }) - -# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("xchgl %2, %%ebx\n\t" \ - "cmpl $0, %%gs:%P7\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchg8b %1\n\t" \ - "xchgl %2, %%ebx" \ - : "=A" (ret), "=m" (*mem) \ - : "DS" (((unsigned long long int) (newval)) \ - & 0xffffffff), \ - "c" (((unsigned long long int) (newval)) >> 32), \ - "m" (*mem), "a" (((unsigned long long int) (oldval)) \ - & 0xffffffff), \ - "d" (((unsigned long long int) (oldval)) >> 32), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) # else # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ @@ -167,22 +112,6 @@ typedef uintmax_t uatomic_max_t; & 0xffffffff), \ "d" (((unsigned long long int) (oldval)) >> 32)); \ ret; }) - -# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%gs:%P7\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchg8b %1" \ - : "=A" (ret), "=m" (*mem) \ - : "b" (((unsigned long long int) (newval)) \ - & 0xffffffff), \ - "c" (((unsigned long long int) (newval)) >> 32), \ - "m" (*mem), "a" (((unsigned long long int) (oldval)) \ - & 0xffffffff), \ - "d" (((unsigned long long int) (oldval)) >> 32), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) # endif #endif @@ -210,24 +139,21 @@ typedef uintmax_t uatomic_max_t; result; }) -#define __arch_exchange_and_add_body(lock, pfx, mem, value) \ +#define atomic_exchange_and_add(mem, value) \ ({ __typeof (*mem) __result; \ __typeof (value) __addval = (value); \ if (sizeof (*mem) == 1) \ - __asm __volatile (lock "xaddb %b0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \ : "=r" (__result), "=m" (*mem) \ - : "0" (__addval), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" (__addval), "m" (*mem)); \ else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "xaddw %w0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \ : "=r" (__result), "=m" (*mem) \ - : "0" (__addval), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" (__addval), "m" (*mem)); \ else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "xaddl %0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \ : "=r" (__result), "=m" (*mem) \ - : "0" (__addval), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" (__addval), "m" (*mem)); \ else \ { \ __typeof (mem) __memp = (mem); \ @@ -235,64 +161,41 @@ typedef uintmax_t uatomic_max_t; __result = *__memp; \ do \ __tmpval = __result; \ - while ((__result = pfx##_compare_and_exchange_val_64_acq \ + while ((__result = __arch_compare_and_exchange_val_64_acq \ (__memp, __result + __addval, __result)) == __tmpval); \ } \ __result; }) -#define atomic_exchange_and_add(mem, value) \ - __arch_exchange_and_add_body (LOCK_PREFIX, __arch, mem, value) - -#define __arch_exchange_and_add_cprefix \ - "cmpl $0, %%gs:%P4\n\tje 0f\n\tlock\n0:\t" - -#define catomic_exchange_and_add(mem, value) \ - __arch_exchange_and_add_body (__arch_exchange_and_add_cprefix, __arch_c, \ - mem, value) - - -#define __arch_add_body(lock, pfx, mem, value) \ - do { \ - if (__builtin_constant_p (value) && (value) == 1) \ - atomic_increment (mem); \ - else if (__builtin_constant_p (value) && (value) == -1) \ - atomic_decrement (mem); \ - else if (sizeof (*mem) == 1) \ - __asm __volatile (lock "addb %b1, %0" \ - : "=m" (*mem) \ - : "ir" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "addw %w1, %0" \ - : "=m" (*mem) \ - : "ir" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "addl %1, %0" \ - : "=m" (*mem) \ - : "ir" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - { \ - __typeof (value) __addval = (value); \ - __typeof (mem) __memp = (mem); \ - __typeof (*mem) __oldval = *__memp; \ - __typeof (*mem) __tmpval; \ - do \ - __tmpval = __oldval; \ - while ((__oldval = pfx##_compare_and_exchange_val_64_acq \ - (__memp, __oldval + __addval, __oldval)) == __tmpval); \ - } \ - } while (0) #define atomic_add(mem, value) \ - __arch_add_body (LOCK_PREFIX, __arch, mem, value) - -#define __arch_add_cprefix \ - "cmpl $0, %%gs:%P3\n\tje 0f\n\tlock\n0:\t" - -#define catomic_add(mem, value) \ - __arch_add_body (__arch_add_cprefix, __arch_c, mem, value) + (void) ({ if (__builtin_constant_p (value) && (value) == 1) \ + atomic_increment (mem); \ + else if (__builtin_constant_p (value) && (value) == -1) \ + atomic_decrement (mem); \ + else if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "addb %b1, %0" \ + : "=m" (*mem) \ + : "ir" (value), "m" (*mem)); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "addw %w1, %0" \ + : "=m" (*mem) \ + : "ir" (value), "m" (*mem)); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "addl %1, %0" \ + : "=m" (*mem) \ + : "ir" (value), "m" (*mem)); \ + else \ + { \ + __typeof (value) __addval = (value); \ + __typeof (mem) __memp = (mem); \ + __typeof (*mem) __oldval = *__memp; \ + __typeof (*mem) __tmpval; \ + do \ + __tmpval = __oldval; \ + while ((__oldval = __arch_compare_and_exchange_val_64_acq \ + (__memp, __oldval + __addval, __oldval)) == __tmpval); \ + } \ + }) #define atomic_add_negative(mem, value) \ @@ -333,42 +236,30 @@ typedef uintmax_t uatomic_max_t; __result; }) -#define __arch_increment_body(lock, pfx, mem) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (lock "incb %b0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "incw %w0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "incl %0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - { \ - __typeof (mem) __memp = (mem); \ - __typeof (*mem) __oldval = *__memp; \ - __typeof (*mem) __tmpval; \ - do \ - __tmpval = __oldval; \ - while ((__oldval = pfx##_compare_and_exchange_val_64_acq \ - (__memp, __oldval + 1, __oldval)) == __tmpval); \ - } \ - } while (0) - -#define atomic_increment(mem) __arch_increment_body (LOCK_PREFIX, __arch, mem) - -#define __arch_increment_cprefix \ - "cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t" - -#define catomic_increment(mem) \ - __arch_increment_body (__arch_increment_cprefix, __arch_c, mem) +#define atomic_increment(mem) \ + (void) ({ if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "incb %b0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "incw %w0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "incl %0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __typeof (*mem) __oldval = *__memp; \ + __typeof (*mem) __tmpval; \ + do \ + __tmpval = __oldval; \ + while ((__oldval = __arch_compare_and_exchange_val_64_acq \ + (__memp, __oldval + 1, __oldval)) == __tmpval); \ + } \ + }) #define atomic_increment_and_test(mem) \ @@ -390,42 +281,30 @@ typedef uintmax_t uatomic_max_t; __result; }) -#define __arch_decrement_body(lock, pfx, mem) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (lock "decb %b0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "decw %w0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "decl %0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - { \ - __typeof (mem) __memp = (mem); \ - __typeof (*mem) __oldval = *__memp; \ - __typeof (*mem) __tmpval; \ - do \ - __tmpval = __oldval; \ - while ((__oldval = pfx##_compare_and_exchange_val_64_acq \ - (__memp, __oldval - 1, __oldval)) == __tmpval); \ - } \ - } while (0) - -#define atomic_decrement(mem) __arch_decrement_body (LOCK_PREFIX, __arch, mem) - -#define __arch_decrement_cprefix \ - "cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t" - -#define catomic_decrement(mem) \ - __arch_decrement_body (__arch_decrement_cprefix, __arch_c, mem) +#define atomic_decrement(mem) \ + (void) ({ if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "decb %b0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "decw %w0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "decl %0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __typeof (*mem) __oldval = *__memp; \ + __typeof (*mem) __tmpval; \ + do \ + __tmpval = __oldval; \ + while ((__oldval = __arch_compare_and_exchange_val_64_acq \ + (__memp, __oldval - 1, __oldval)) == __tmpval); \ + } \ + }) #define atomic_decrement_and_test(mem) \ @@ -448,22 +327,21 @@ typedef uintmax_t uatomic_max_t; #define atomic_bit_set(mem, bit) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (LOCK_PREFIX "orb %b2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "ir" (1 << (bit))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (LOCK_PREFIX "orw %w2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "ir" (1 << (bit))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (LOCK_PREFIX "orl %2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "ir" (1 << (bit))); \ - else \ - abort (); \ - } while (0) + (void) ({ if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "orb %b2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "ir" (1 << (bit))); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "orw %w2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "ir" (1 << (bit))); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "orl %2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "ir" (1 << (bit))); \ + else \ + abort (); \ + }) #define atomic_bit_test_set(mem, bit) \ @@ -486,51 +364,3 @@ typedef uintmax_t uatomic_max_t; #define atomic_delay() asm ("rep; nop") - - -#define atomic_and(mem, mask) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (LOCK_PREFIX "andb %1, %b0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (LOCK_PREFIX "andw %1, %w0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (LOCK_PREFIX "andl %1, %0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - else \ - abort (); \ - } while (0) - - -#define __arch_or_body(lock, mem, mask) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (lock "orb %1, %b0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "orw %1, %w0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "orl %1, %0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - abort (); \ - } while (0) - -#define atomic_or(mem, mask) __arch_or_body (LOCK_PREFIX, mem, mask) - -#define __arch_or_cprefix \ - "cmpl $0, %%gs:%P3\n\tje 0f\n\tlock\n0:\t" - -#define catomic_or(mem, mask) __arch_or_body (__arch_or_cprefix, mem, mask) diff --git a/sysdeps/i386/i686/memcmp.S b/sysdeps/i386/i686/memcmp.S index 4fa6adea98..4bd5394bec 100644 --- a/sysdeps/i386/i686/memcmp.S +++ b/sysdeps/i386/i686/memcmp.S @@ -1,5 +1,5 @@ /* Compare two memory blocks for differences in the first COUNT bytes. - Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -44,9 +44,13 @@ absolute address. */ \ addl (%ebx,INDEX,4), %ebx +#ifdef HAVE_HIDDEN .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits .globl __i686.get_pc_thunk.bx .hidden __i686.get_pc_thunk.bx +#else + .text +#endif ALIGN (4) .type __i686.get_pc_thunk.bx,@function __i686.get_pc_thunk.bx: @@ -380,38 +384,38 @@ END (BP_SYM (memcmp)) .section .rodata ALIGN (2) L(table_32bytes) : - .long L(0bytes) - L(table_32bytes) - .long L(1bytes) - L(table_32bytes) - .long L(2bytes) - L(table_32bytes) - .long L(3bytes) - L(table_32bytes) - .long L(4bytes) - L(table_32bytes) - .long L(5bytes) - L(table_32bytes) - .long L(6bytes) - L(table_32bytes) - .long L(7bytes) - L(table_32bytes) - .long L(8bytes) - L(table_32bytes) - .long L(9bytes) - L(table_32bytes) - .long L(10bytes) - L(table_32bytes) - .long L(11bytes) - L(table_32bytes) - .long L(12bytes) - L(table_32bytes) - .long L(13bytes) - L(table_32bytes) - .long L(14bytes) - L(table_32bytes) - .long L(15bytes) - L(table_32bytes) - .long L(16bytes) - L(table_32bytes) - .long L(17bytes) - L(table_32bytes) - .long L(18bytes) - L(table_32bytes) - .long L(19bytes) - L(table_32bytes) - .long L(20bytes) - L(table_32bytes) - .long L(21bytes) - L(table_32bytes) - .long L(22bytes) - L(table_32bytes) - .long L(23bytes) - L(table_32bytes) - .long L(24bytes) - L(table_32bytes) - .long L(25bytes) - L(table_32bytes) - .long L(26bytes) - L(table_32bytes) - .long L(27bytes) - L(table_32bytes) - .long L(28bytes) - L(table_32bytes) - .long L(29bytes) - L(table_32bytes) - .long L(30bytes) - L(table_32bytes) - .long L(31bytes) - L(table_32bytes) + .long L(0bytes) - . + 0x0 + .long L(1bytes) - . + 0x4 + .long L(2bytes) - . + 0x8 + .long L(3bytes) - . + 0xc + .long L(4bytes) - . + 0x10 + .long L(5bytes) - . + 0x14 + .long L(6bytes) - . + 0x18 + .long L(7bytes) - . + 0x1c + .long L(8bytes) - . + 0x20 + .long L(9bytes) - . + 0x24 + .long L(10bytes) - . + 0x28 + .long L(11bytes) - . + 0x2c + .long L(12bytes) - . + 0x30 + .long L(13bytes) - . + 0x34 + .long L(14bytes) - . + 0x38 + .long L(15bytes) - . + 0x3c + .long L(16bytes) - . + 0x40 + .long L(17bytes) - . + 0x44 + .long L(18bytes) - . + 0x48 + .long L(19bytes) - . + 0x4c + .long L(20bytes) - . + 0x50 + .long L(21bytes) - . + 0x54 + .long L(22bytes) - . + 0x58 + .long L(23bytes) - . + 0x5c + .long L(24bytes) - . + 0x60 + .long L(25bytes) - . + 0x64 + .long L(26bytes) - . + 0x68 + .long L(27bytes) - . + 0x6c + .long L(28bytes) - . + 0x70 + .long L(29bytes) - . + 0x74 + .long L(30bytes) - . + 0x78 + .long L(31bytes) - . + 0x7c #undef bcmp diff --git a/sysdeps/i386/ldbl2mpn.c b/sysdeps/i386/ldbl2mpn.c index bf4e4ff43f..01be777270 100644 --- a/sysdeps/i386/ldbl2mpn.c +++ b/sysdeps/i386/ldbl2mpn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 2000, 2007 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 @@ -19,7 +19,7 @@ #include "gmp.h" #include "gmp-impl.h" #include "longlong.h" -#include "ieee754.h" +#include <ieee754.h> #include <float.h> #include <stdlib.h> @@ -46,7 +46,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, #elif BITS_PER_MP_LIMB == 64 /* Hopefully the compiler will combine the two bitfield extracts and this composition into just the original quadword extract. */ - res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; #define N 1 #else #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" @@ -109,6 +109,13 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, } } } + else if (u.ieee.exponent < 0x7fff +#if N == 2 + && res_ptr[0] == 0 +#endif + && res_ptr[N - 1] == 0) + /* Pseudo zero. */ + *expt = 0; return N; } diff --git a/sysdeps/i386/soft-fp/sfp-machine.h b/sysdeps/i386/soft-fp/sfp-machine.h new file mode 100644 index 0000000000..ed71ae418a --- /dev/null +++ b/sysdeps/i386/soft-fp/sfp-machine.h @@ -0,0 +1,89 @@ +#define _FP_W_TYPE_SIZE 32 +#define _FP_W_TYPE unsigned long +#define _FP_WS_TYPE signed long +#define _FP_I_TYPE long + +#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ + __asm__("addl %5,%1; adcl %3,%0" \ + : "=r"(rh), "=r"(rl) \ + : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl) \ + : "cc") + +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + __asm__ volatile("addl %5,%1; adcl %3,%0" \ + : "=r"(r1), "=r"(r0) \ + : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0) \ + : "cc"); \ + __asm__ volatile("adcl %5,%1; adcl %3,%0" \ + : "=r"(r3), "=r"(r2) \ + : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2) \ + : "cc"); \ + } while (0) + +#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ + __asm__("subl %5,%1; sbbl %4,%0" \ + : "=r"(rh), "=r"(rl) \ + : "0"(xh), "1"(xl), "g"(yh), "g"(yl) \ + : "cc") + +#define __FP_CLZ(r, x) \ + do { \ + __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc"); \ + r ^= 31; \ + } while (0) + +#define _i386_mul_32_64(rh, rl, x, y) \ + __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc") + +#define _i386_div_64_32(q, r, nh, nl, d) \ + __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc") + + +#define _FP_MUL_MEAT_S(R,X,Y) \ + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64) +#define _FP_MUL_MEAT_D(R,X,Y) \ + _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64) + +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) + +#define _FP_NANFRAC_S _FP_QNANBIT_S +#define _FP_NANFRAC_D _FP_QNANBIT_D, 0 +#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 +#define _FP_NANSIGN_S 1 +#define _FP_NANSIGN_D 1 +#define _FP_NANSIGN_Q 1 + +#define _FP_KEEPNANFRACP 1 +/* Here is something Intel misdesigned: the specs don't define + the case where we have two NaNs with same mantissas, but + different sign. Different operations pick up different NaNs. + */ +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if (_FP_FRAC_GT_##wc(X, Y) \ + || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + else \ + { \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R,Y); \ + } \ + R##_c = FP_CLS_NAN; \ + } while (0) + +#define FP_EX_INVALID (1 << 0) +#define FP_EX_DENORM (1 << 1) +#define FP_EX_DIVZERO (1 << 2) +#define FP_EX_OVERFLOW (1 << 3) +#define FP_EX_UNDERFLOW (1 << 4) +#define FP_EX_INEXACT (1 << 5) + +#define FP_RND_NEAREST 0 +#define FP_RND_ZERO 3 +#define FP_RND_PINF 2 +#define FP_RND_MINF 1 diff --git a/sysdeps/i386/sysdep.h b/sysdeps/i386/sysdep.h index e03a8e926d..2739cb00b3 100644 --- a/sysdeps/i386/sysdep.h +++ b/sysdeps/i386/sysdep.h @@ -1,6 +1,5 @@ /* Assembler macros for i386. - Copyright (C) 1991-93,95,96,98,2002,2003,2005,2006 - Free Software Foundation, Inc. + Copyright (C) 1991-93,95,96,98,2002,2003,2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -133,7 +132,15 @@ lose: SYSCALL_PIC_SETUP \ cfi_adjust_cfa_offset (-4); \ addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx; -# define SETUP_PIC_REG(reg) \ +# ifndef HAVE_HIDDEN +# define SETUP_PIC_REG(reg) \ + call 1f; \ + .subsection 1; \ +1:movl (%esp), %e##reg; \ + ret; \ + .previous +# else +# define SETUP_PIC_REG(reg) \ .ifndef __i686.get_pc_thunk.reg; \ .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits; \ .globl __i686.get_pc_thunk.reg; \ @@ -146,6 +153,7 @@ __i686.get_pc_thunk.reg: \ .previous; \ .endif; \ call __i686.get_pc_thunk.reg +# endif # define LOAD_PIC_REG(reg) \ SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h index 61b4ea99a7..55349690e3 100644 --- a/sysdeps/ia64/dl-machine.h +++ b/sysdeps/ia64/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. IA-64 version. - Copyright (C) 1995-1997, 2000-2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-1997, 2000-2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -311,7 +311,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) of the main executable's symbols, as for a COPY reloc, which we don't use. */ /* ??? Ignore *MSB for now. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) #define elf_machine_type_class(type) \ (((type) == R_IA64_IPLTLSB || (type) == R_IA64_DTPMOD64LSB \ || (type) == R_IA64_DTPREL64LSB || (type) == R_IA64_TPREL64LSB) \ @@ -432,7 +432,7 @@ elf_machine_rela (struct link_map *map, value = _dl_make_fptr (sym_map, sym, value); else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_PCREL64LSB)) value -= (Elf64_Addr) reloc_addr & -16; -#if !defined RTLD_BOOTSTRAP || defined USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || defined USE___THREAD) else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPMOD64LSB)) # ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always index 1. */ diff --git a/sysdeps/ia64/fpu/fesetround.c b/sysdeps/ia64/fpu/fesetround.c index 351bcc2f10..13801c848b 100644 --- a/sysdeps/ia64/fpu/fesetround.c +++ b/sysdeps/ia64/fpu/fesetround.c @@ -1,5 +1,5 @@ /* Set current rounding direction. - Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999. @@ -26,7 +26,7 @@ fesetround (int round) fenv_t fpsr; if (round & ~3) - return 0; + return 1; /* Get the current state. */ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr)); @@ -37,6 +37,6 @@ fesetround (int round) /* Put the new state in effect. */ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr) : "memory"); - return 1; + return 0; } libm_hidden_def (fesetround) diff --git a/sysdeps/ia64/ldbl2mpn.c b/sysdeps/ia64/ldbl2mpn.c new file mode 100644 index 0000000000..641b789cd4 --- /dev/null +++ b/sysdeps/ia64/ldbl2mpn.c @@ -0,0 +1 @@ +#include "../i386/ldbl2mpn.c" diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c index 9751284008..2c0eeae86f 100644 --- a/sysdeps/ia64/libc-tls.c +++ b/sysdeps/ia64/libc-tls.c @@ -1,5 +1,5 @@ /* Thread-local storage handling in the ELF dynamic linker. IA-64 version. - Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -19,6 +19,8 @@ #include <csu/libc-tls.c> +#if USE_TLS + /* On IA-64, as it lacks linker optimizations, __tls_get_addr can be called even in statically linked binaries. In this case module must be always 1 and PT_TLS segment @@ -30,3 +32,5 @@ __tls_get_addr (size_t m, size_t offset) dtv_t *dtv = THREAD_DTV (); return (char *) dtv[1].pointer.val + offset; } + +#endif diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c index d9bd8b479f..1e159f2c0b 100644 --- a/sysdeps/ieee754/dbl-64/e_pow.c +++ b/sysdeps/ieee754/dbl-64/e_pow.c @@ -106,20 +106,28 @@ double __ieee754_pow(double x, double y) { else return y < 0 ? 1.0/ABS(x) : 0.0; /* return 0 */ } + + qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */ + qy = v.i[HIGH_HALF]&0x7fffffff; /* no sign */ + + if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) return NaNQ.x; + if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0)) + return x == 1.0 ? 1.0 : NaNQ.x; + /* if x<0 */ if (u.i[HIGH_HALF] < 0) { k = checkint(y); if (k==0) { - if ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) { + if (qy == 0x7ff00000) { if (x == -1.0) return 1.0; else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0; else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x; } - else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0) + else if (qx == 0x7ff00000) return y < 0 ? 0.0 : INF.x; return NaNQ.x; /* y not integer and x<0 */ } - else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0) + else if (qx == 0x7ff00000) { if (k < 0) return y < 0 ? nZERO.x : nINF.x; @@ -129,14 +137,6 @@ double __ieee754_pow(double x, double y) { return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */ } /* x>0 */ - qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */ - qy = v.i[HIGH_HALF]&0x7fffffff; /* no sign */ - - if (qx > 0x7ff00000 || (qx == 0x7ff00000 && u.i[LOW_HALF] != 0)) return NaNQ.x; - /* if 0<x<2^-0x7fe */ - if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0)) - return x == 1.0 ? 1.0 : NaNQ.x; - /* if y<2^-0x7fe */ if (qx == 0x7ff00000) /* x= 2^-0x3ff */ {if (y == 0) return NaNQ.x; diff --git a/sysdeps/ieee754/flt-32/s_nextafterf.c b/sysdeps/ieee754/flt-32/s_nextafterf.c index e1568e24c9..600c14621f 100644 --- a/sysdeps/ieee754/flt-32/s_nextafterf.c +++ b/sysdeps/ieee754/flt-32/s_nextafterf.c @@ -18,7 +18,7 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp #endif #include "math.h" -#include "math_private.h" +#include <math_private.h> #include <float.h> #ifdef __STDC__ @@ -40,9 +40,12 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp return x+y; if(x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ + float u; SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u*u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if(hx>hy) { /* x > y, x -= ulp */ @@ -61,15 +64,12 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp if(hy>=0x7f800000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0) - asm ("" : "=m"(x) : "m"(x)); + asm ("" : "+m"(x)); return x; /* overflow */ } - if(hy<0x00800000) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ - SET_FLOAT_WORD(y,hx); - return y; - } + if(hy<0x00800000) { + float u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/ieee754/ldbl-128/s_nextafterl.c b/sysdeps/ieee754/ldbl-128/s_nextafterl.c index d3df668178..7bc869a518 100644 --- a/sysdeps/ieee754/ldbl-128/s_nextafterl.c +++ b/sysdeps/ieee754/ldbl-128/s_nextafterl.c @@ -25,7 +25,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> #ifdef __STDC__ long double __nextafterl(long double x, long double y) @@ -47,9 +47,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if(x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ + long double u; SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ @@ -70,12 +73,9 @@ static char rcsid[] = "$NetBSD: $"; } hy = hx&0x7fff000000000000LL; if(hy==0x7fff000000000000LL) return x+x;/* overflow */ - if(hy==0) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ - SET_LDOUBLE_WORDS64(y,hx,lx); - return y; - } + if(hy==0) { + long double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_LDOUBLE_WORDS64(x,hx,lx); return x; diff --git a/sysdeps/ieee754/ldbl-128/s_nexttoward.c b/sysdeps/ieee754/ldbl-128/s_nexttoward.c index 553e401973..178505c58f 100644 --- a/sysdeps/ieee754/ldbl-128/s_nexttoward.c +++ b/sysdeps/ieee754/ldbl-128/s_nexttoward.c @@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> #include <float.h> #ifdef __STDC__ @@ -53,10 +53,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ - double x2; + double u; INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if (hy<0||(ix>>20)>(iy>>48)-0x3c00 @@ -87,16 +89,13 @@ static char rcsid[] = "$NetBSD: $"; if(hy>=0x7ff00000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to float. */ - asm ("" : "=m"(x) : "m"(x)); + /* Force conversion to double. */ + asm ("" : "+m"(x)); return x; } - if(hy<0x00100000) { /* underflow */ - double x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - INSERT_WORDS(x2,hx,lx); - return x2; - } + if(hy<0x00100000) { + double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } INSERT_WORDS(x,hx,lx); return x; diff --git a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c index 8a2d45e2d8..21d1e62dab 100644 --- a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c +++ b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006 +/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -31,19 +31,20 @@ long double __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) { union ibm_extended_long_double u; - unsigned long hidden2, lzcount; + unsigned long lzcount; unsigned long long hi, lo; + int exponent2; u.ieee.negative = sign; u.ieee.negative2 = sign; u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS; - u.ieee.exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; + u.ieee.exponent2 = 0; + exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; #if BITS_PER_MP_LIMB == 32 /* The low order 53 bits (52 + hidden) go into the lower double */ lo = frac_ptr[0]; lo |= (frac_ptr[1] & ((1LL << (53 - 32)) - 1)) << 32; - hidden2 = (frac_ptr[1] >> (52 - 32)) & ((mp_limb_t) 1); /* The high order 53 bits (52 + hidden) go into the upper double */ hi = (frac_ptr[1] >> (53 - 32)) & ((1 << 11) - 1); hi |= ((unsigned long long) frac_ptr[2]) << 11; @@ -51,7 +52,6 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) #elif BITS_PER_MP_LIMB == 64 /* The low order 53 bits (52 + hidden) go into the lower double */ lo = frac_ptr[0] & (((mp_limb_t) 1 << 53) - 1); - hidden2 = (frac_ptr[0] >> 52) & ((mp_limb_t) 1); /* The high order 53 bits (52 + hidden) go into the upper double */ hi = (frac_ptr[0] >> 53) & (((mp_limb_t) 1 << 11) - 1); hi |= (frac_ptr[1] << 11); @@ -59,14 +59,62 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" #endif + if ((hi & (1LL << 52)) == 0 && (hi | lo) != 0) + { + /* denormal number */ + unsigned long long val = hi ? hi : lo; + + if (sizeof (val) == sizeof (long)) + lzcount = __builtin_clzl (val); + else if ((val >> 32) != 0) + lzcount = __builtin_clzl ((long) (val >> 32)); + else + lzcount = __builtin_clzl ((long) val) + 32; + if (hi) + lzcount = lzcount - 11; + else + lzcount = lzcount + 42; + + if (lzcount > u.ieee.exponent) + { + lzcount = u.ieee.exponent; + u.ieee.exponent = 0; + exponent2 -= lzcount; + } + else + { + u.ieee.exponent -= (lzcount - 1); + exponent2 -= (lzcount - 1); + } + + if (lzcount <= 53) + { + hi = (hi << lzcount) | (lo >> (53 - lzcount)); + lo = (lo << lzcount) & ((1LL << 53) - 1); + } + else + { + hi = lo << (lzcount - 53); + lo = 0; + } + } + if (lo != 0L) { /* hidden2 bit of low double controls rounding of the high double. - If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) + If hidden2 is '1' and either the explicit mantissa is non-zero + or hi is odd, then round up hi and adjust lo (2nd mantissa) plus change the sign of the low double to compensate. */ - if (hidden2) + if ((lo & (1LL << 52)) != 0 + && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)))) { hi++; + if ((hi & ((1LL << 52) - 1)) == 0) + { + if ((hi & (1LL << 53)) != 0) + hi -= 1LL << 52; + u.ieee.exponent++; + } u.ieee.negative2 = !sign; lo = (1LL << 53) - lo; } @@ -85,17 +133,18 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) if (lzcount > 0) { lo = lo << lzcount; - u.ieee.exponent2 = u.ieee.exponent2 - lzcount; + exponent2 = exponent2 - lzcount; } + if (exponent2 > 0) + u.ieee.exponent2 = exponent2; + else + lo >>= 1 - exponent2; } else - { - u.ieee.negative2 = 0; - u.ieee.exponent2 = 0; - } + u.ieee.negative2 = 0; u.ieee.mantissa3 = lo & 0xffffffffLL; - u.ieee.mantissa2 = (lo >> 32) & 0xffffff; + u.ieee.mantissa2 = (lo >> 32) & 0xfffff; u.ieee.mantissa1 = hi & 0xffffffffLL; u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1); diff --git a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c index 2a7b70fabf..b2ad25e31f 100644 --- a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +++ b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c @@ -1,5 +1,5 @@ /* Print floating point number in hexadecimal notation according to ISO C99. - Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006 + Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -35,21 +35,24 @@ do { \ \ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ - /* If the lower double is not a denomal or zero then set the hidden \ - 53rd bit. */ \ - if (eldbl.ieee.exponent2 > 0x001) \ - { \ - lo |= (1ULL << 52); \ - lo = lo << 7; /* pre-shift lo to match ieee854. */ \ - /* The lower double is normalized separately from the upper. We \ - may need to adjust the lower manitissa to reflect this. */ \ - ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ - if (ediff > 53) \ - lo = lo >> (ediff-53); \ - } \ - \ - if ((eldbl.ieee.negative != eldbl.ieee.negative2) \ - && ((eldbl.ieee.exponent2 != 0) && (lo != 0L))) \ + lo <<= 7; /* pre-shift lo to match ieee854. */ \ + /* If the lower double is not a denomal or zero then set the hidden \ + 53rd bit. */ \ + if (eldbl.ieee.exponent2 != 0) \ + lo |= (1ULL << (52 + 7)); \ + else \ + lo <<= 1; \ + /* The lower double is normalized separately from the upper. We \ + may need to adjust the lower manitissa to reflect this. */ \ + ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ + if (ediff > 53 + 63) \ + lo = 0; \ + else if (ediff > 53) \ + lo = lo >> (ediff - 53); \ + else if (eldbl.ieee.exponent2 == 0 && ediff < 53) \ + lo = lo << (53 - ediff); \ + if (eldbl.ieee.negative != eldbl.ieee.negative2 \ + && (eldbl.ieee.exponent2 != 0 || lo != 0L)) \ { \ lo = (1ULL << 60) - lo; \ if (hi == 0L) \ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c b/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c index 3ca178a3c5..6999abc250 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c @@ -1,5 +1,5 @@ /* Return classification value corresponding to argument. - Copyright (C) 1997,1999,2002,2004,2006 Free Software Foundation, Inc. + Copyright (C) 1997,1999,2002,2004,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and Jakub Jelinek <jj@ultra.linux.cz>, 1999. @@ -30,14 +30,16 @@ * -NaN fffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx * +Inf 7ff0 0000 0000 0000 xxxx xxxx xxxx xxxx * -Inf fff0 0000 0000 0000 xxxx xxxx xxxx xxxx - * +0 0000 0000 0000 0000 - * -0 8000 0000 0000 0000 - * +normal 001n nnnn nnnn nnnn (smallest) - * -normal 801n nnnn nnnn nnnn (smallest) - * +normal 7fen nnnn nnnn nnnn (largest) - * -normal ffen nnnn nnnn nnnn (largest) - * +denorm 000n nnnn nnnn nnnn - * -denorm 800n nnnn nnnn nnnn + * +0 0000 0000 0000 0000 xxxx xxxx xxxx xxxx + * -0 8000 0000 0000 0000 xxxx xxxx xxxx xxxx + * +normal 0360 0000 0000 0000 0000 0000 0000 0000 (smallest) + * -normal 8360 0000 0000 0000 0000 0000 0000 0000 (smallest) + * +normal 7fef ffff ffff ffff 7c8f ffff ffff fffe (largest) + * +normal ffef ffff ffff ffff fc8f ffff ffff fffe (largest) + * +denorm 0360 0000 0000 0000 8000 0000 0000 0001 (largest) + * -denorm 8360 0000 0000 0000 0000 0000 0000 0001 (largest) + * +denorm 000n nnnn nnnn nnnn xxxx xxxx xxxx xxxx + * -denorm 800n nnnn nnnn nnnn xxxx xxxx xxxx xxxx */ int @@ -59,12 +61,23 @@ ___fpclassifyl (long double x) /* +/-zero or +/- normal or +/- denormal */ if (hx & 0x7fffffffffffffffULL) { /* +/- normal or +/- denormal */ - if ((hx & 0x7ff0000000000000ULL) >= 0x0360000000000000ULL) { + if ((hx & 0x7ff0000000000000ULL) > 0x0360000000000000ULL) { /* +/- normal */ retval = FP_NORMAL; } else { - /* +/- denormal */ - retval = FP_SUBNORMAL; + if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) { + if ((lx & 0x7fffffffffffffff) /* lower is non-zero */ + && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */ + /* +/- denormal */ + retval = FP_SUBNORMAL; + } else { + /* +/- normal */ + retval = FP_NORMAL; + } + } else { + /* +/- denormal */ + retval = FP_SUBNORMAL; + } } } else { /* +/- zero */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c index e35ce50829..39d0e6a5e3 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c @@ -24,8 +24,8 @@ static char rcsid[] = "$NetBSD: $"; * Special cases: */ -#include "math.h" -#include "math_private.h" +#include <math.h> +#include <math_private.h> #include <math_ldbl_opt.h> #ifdef __STDC__ @@ -35,7 +35,7 @@ static char rcsid[] = "$NetBSD: $"; long double x,y; #endif { - int64_t hx,hy,ihx,ihy,ilx,ily; + int64_t hx,hy,ihx,ihy,ilx; u_int64_t lx,ly; GET_LDOUBLE_WORDS64(hx,lx,x); @@ -43,7 +43,6 @@ static char rcsid[] = "$NetBSD: $"; ihx = hx&0x7fffffffffffffffLL; /* |hx| */ ilx = lx&0x7fffffffffffffffLL; /* |lx| */ ihy = hy&0x7fffffffffffffffLL; /* |hy| */ - ily = ly&0x7fffffffffffffffLL; /* |ly| */ if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&& ((ihx&0x000fffffffffffffLL)!=0)) || /* x is nan */ @@ -53,55 +52,67 @@ static char rcsid[] = "$NetBSD: $"; if(x==y) return y; /* x=y, return y */ if(ihx == 0 && ilx == 0) { /* x == 0 */ - SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + long double u; + hy = (hy & 0x8000000000000000ULL) | 1; + SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } - if(ihx>=0) { /* x > 0 */ - if(ihx>ihy||((ihx==ihy)&&(ilx>ily))) { /* x > y, x -= ulp */ - - if(ilx==0) - hx--; - else - lx--; - } else { /* x < y, x += ulp */ - if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL)) - { - SET_LDOUBLE_WORDS64(x,0x7ff0000000000000,0x8000000000000000); - return x; - } - else if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL)) - { - SET_LDOUBLE_WORDS64(x,0xfff0000000000000,0x8000000000000000); - return x; - } - else if((lx&0x7fffffffffffffff)==0) hx++; - else - lx++; + + long double u; + if(x > y) { /* x > y, x -= ulp */ + if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL)) + return x+x; /* overflow, return -inf */ + if (hx >= 0x7ff0000000000000LL) { + SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL); + return u; } - } else { /* x < 0 */ - if(ihy>=0||ihx>ihy||((ihx==ihy)&&(ilx>ily))){/* x < y, x -= ulp */ - if((lx&0x7fffffffffffffff)==0) - hx--; - else - lx--; - } else { /* x > y, x += ulp */ - if((lx&0x7fffffffffffffff)==0) hx++; - else - lx++; + if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ + u = math_opt_barrier (x); + x -= __LDBL_DENORM_MIN__; + if (ihx < 0x0360000000000000LL + || (hx > 0 && (int64_t) lx <= 0) + || (hx < 0 && (int64_t) lx > 1)) { + u = u * u; + math_force_eval (u); /* raise underflow flag */ + } + return x; } - } - hy = hx&0x7ff0000000000000LL; - if(hy==0x7ff0000000000000LL) return x+x;/* overflow */ - if(hy==0) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ - SET_LDOUBLE_WORDS64(y,hx,lx); - return y; + if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ + SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); + u *= 0x1.0000000000000p-105L; + } else + SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); + return x - u; + } else { /* x < y, x += ulp */ + if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL)) + return x+x; /* overflow, return +inf */ + if ((u_int64_t) hx >= 0xfff0000000000000ULL) { + SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL); + return u; + } + if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ + u = math_opt_barrier (x); + x += __LDBL_DENORM_MIN__; + if (ihx < 0x0360000000000000LL + || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL) + || (hx < 0 && (int64_t) lx >= 0)) { + u = u * u; + math_force_eval (u); /* raise underflow flag */ + } + if (x == 0.0L) /* handle negative __LDBL_DENORM_MIN__ case */ + x = -0.0L; + return x; } + if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ + SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); + u *= 0x1.0000000000000p-105L; + } else + SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); + return x + u; } - SET_LDOUBLE_WORDS64(x,hx,lx); - return x; } strong_alias (__nextafterl, __nexttowardl) long_double_symbol (libm, __nextafterl, nextafterl); diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c index 3335100592..e2f6521f57 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c @@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> #include <math_ldbl_opt.h> #include <float.h> @@ -55,10 +55,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ - double x2; + double u; INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if (hy<0||(ix>>20)>(iy>>52) @@ -89,16 +91,13 @@ static char rcsid[] = "$NetBSD: $"; if(hy>=0x7ff00000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to float. */ - asm ("" : "=m"(x) : "m"(x)); + /* Force conversion to double. */ + asm ("" : "+m"(x)); return x; } - if(hy<0x00100000) { /* underflow */ - double x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - INSERT_WORDS(x2,hx,lx); - return x2; - } + if(hy<0x00100000) { + double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } INSERT_WORDS(x,hx,lx); return x; diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c index a9373ff822..cf655fad16 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c @@ -19,8 +19,9 @@ static char rcsid[] = "$NetBSD: $"; #endif #include "math.h" -#include "math_private.h" +#include <math_private.h> #include <math_ldbl_opt.h> +#include <float.h> #ifdef __STDC__ float __nexttowardf(float x, long double y) @@ -46,10 +47,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float x2; + float u; SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if(hy<0||(ix>>23)>(iy>>52)-0x380 @@ -69,13 +72,16 @@ static char rcsid[] = "$NetBSD: $"; } } hy = hx&0x7f800000; - if(hy>=0x7f800000) return x+x; /* overflow */ + if(hy>=0x7f800000) { + x = x+x; /* overflow */ + if (FLT_EVAL_METHOD != 0) + /* Force conversion to float. */ + asm ("" : "+m"(x)); + return x; + } if(hy<0x00800000) { /* underflow */ - float x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - SET_FLOAT_WORD(x2,hx); - return x2; - } + float u = x*x; + math_force_eval (u); /* raise underflow flag */ } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/ieee754/ldbl-96/s_nextafterl.c b/sysdeps/ieee754/ldbl-96/s_nextafterl.c index 1798261b28..ed0877d6dd 100644 --- a/sysdeps/ieee754/ldbl-96/s_nextafterl.c +++ b/sysdeps/ieee754/ldbl-96/s_nextafterl.c @@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> #ifdef __STDC__ long double __nextafterl(long double x, long double y) @@ -48,9 +48,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if(x==y) return y; /* x=y, return y */ if((ix|hx|lx)==0) { /* x == 0 */ + long double u; SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(esx<0x8000) { /* x > 0 */ if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) { @@ -85,13 +88,10 @@ static char rcsid[] = "$NetBSD: $"; } } esy = esx&0x7fff; - if(esy==0x7fff) return x+x; /* overflow */ - if(esy==0) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ - SET_LDOUBLE_WORDS(y,esx,hx,lx); - return y; - } + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0) { + long double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_LDOUBLE_WORDS(x,esx,hx,lx); return x; diff --git a/sysdeps/ieee754/ldbl-96/s_nexttoward.c b/sysdeps/ieee754/ldbl-96/s_nexttoward.c index 7945cb5cb1..e30438482c 100644 --- a/sysdeps/ieee754/ldbl-96/s_nexttoward.c +++ b/sysdeps/ieee754/ldbl-96/s_nexttoward.c @@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include "math_private.h" +#include <math_private.h> #include <float.h> #ifdef __STDC__ @@ -50,10 +50,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ - double x2; + double u; INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 @@ -84,16 +86,13 @@ static char rcsid[] = "$NetBSD: $"; if(hy>=0x7ff00000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to float. */ - asm ("" : "=m"(x) : "m"(x)); + /* Force conversion to double. */ + asm ("" : "+m"(x)); return x; } - if(hy<0x00100000) { /* underflow */ - double x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - INSERT_WORDS(x2,hx,lx); - return x2; - } + if(hy<0x00100000) { + double u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } INSERT_WORDS(x,hx,lx); return x; diff --git a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c index a1c38b5d4c..6357975ffc 100644 --- a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c +++ b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c @@ -18,7 +18,8 @@ static char rcsid[] = "$NetBSD: $"; #endif #include "math.h" -#include "math_private.h" +#include <math_private.h> +#include <float.h> #ifdef __STDC__ float __nexttowardf(float x, long double y) @@ -41,10 +42,12 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float x2; + float u; SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 @@ -64,13 +67,16 @@ static char rcsid[] = "$NetBSD: $"; } } hy = hx&0x7f800000; - if(hy>=0x7f800000) return x+x; /* overflow */ - if(hy<0x00800000) { /* underflow */ - float x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - SET_FLOAT_WORD(x2,hx); - return x2; - } + if(hy>=0x7f800000) { + x = x+x; /* overflow */ + if (FLT_EVAL_METHOD != 0) + /* Force conversion to float. */ + asm ("" : "+m"(x)); + return x; + } + if(hy<0x00800000) { + float u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c index d52526f719..68027f26fa 100644 --- a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c +++ b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c @@ -20,7 +20,10 @@ * Special cases: */ +#include <math.h> +#include <math_private.h> #include <math_ldbl_opt.h> +#include <float.h> float __nldbl_nexttowardf(float x, double y); @@ -39,10 +42,12 @@ float __nldbl_nexttowardf(float x, double y) return x+y; if((double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float x2; + float u; SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/ - x2 = x*x; - if(x2==x) return x2; else return x; /* raise underflow flag */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; } if(hx>=0) { /* x > 0 */ if(hy<0||(ix>>23)>(iy>>20)-0x380 @@ -60,13 +65,16 @@ float __nldbl_nexttowardf(float x, double y) hx += 1; } hy = hx&0x7f800000; - if(hy>=0x7f800000) return x+x; /* overflow */ - if(hy<0x00800000) { /* underflow */ - float x2 = x*x; - if(x2!=x) { /* raise underflow flag */ - SET_FLOAT_WORD(x2,hx); - return x2; - } + if(hy>=0x7f800000) { + x = x+x; /* overflow */ + if (FLT_EVAL_METHOD != 0) + /* Force conversion to float. */ + asm ("" : "+m"(x)); + return x; + } + if(hy<0x00800000) { + float u = x*x; /* underflow */ + math_force_eval (u); /* raise underflow flag */ } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index 3288f186e5..fa7da60204 100644 --- a/sysdeps/mach/hurd/fork.c +++ b/sysdeps/mach/hurd/fork.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005,2006 +/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -532,9 +532,11 @@ __fork (void) /* Set the child user thread up to return 1 from the setjmp above. */ _hurd_longjmp_thread_state (&state, env, 1); +#if USE_TLS /* Do special thread setup for TLS if needed. */ if (err = _hurd_tls_fork (thread, &state)) LOSE; +#endif if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR, (natural_t *) &state, statecount)) diff --git a/sysdeps/mach/hurd/futimes.c b/sysdeps/mach/hurd/futimes.c index 4628eee2c3..ca687b8bdf 100644 --- a/sysdeps/mach/hurd/futimes.c +++ b/sysdeps/mach/hurd/futimes.c @@ -1,5 +1,5 @@ /* futimes -- change access and modification times of open file. Hurd version. - Copyright (C) 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2002 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 @@ -28,24 +28,20 @@ int __futimes (int fd, const struct timeval tvp[2]) { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - const union tv *u = (const union tv *) tvp; - union tv nulltv[2]; + struct timeval timevals[2]; error_t err; if (tvp == NULL) { /* Setting the number of microseconds to `-1' tells the underlying filesystems to use the current time. */ - nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; - u = nulltv; + timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1; + tvp = timevals; } - err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt)); + err = HURD_DPORT_USE (fd, __file_utimes (port, + *(time_value_t *) &tvp[0], + *(time_value_t *) &tvp[1])); return err ? __hurd_dfail (fd, err) : 0; } weak_alias (__futimes, futimes) diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h index 972cac57a1..223a47d2f2 100644 --- a/sysdeps/mach/hurd/i386/tls.h +++ b/sysdeps/mach/hurd/i386/tls.h @@ -1,5 +1,5 @@ /* Definitions for thread-local data handling. Hurd/i386 version. - Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,9 @@ /* Some things really need not be machine-dependent. */ # include <sysdeps/mach/hurd/tls.h> +/* Indiciate that TLS support is available. */ +# define USE_TLS 1 + /* The TCB can have any size and the memory following the address the thread pointer points to is unspecified. Allocate the TCB there. */ # define TLS_TCB_AT_TP 1 diff --git a/sysdeps/mach/hurd/lutimes.c b/sysdeps/mach/hurd/lutimes.c index bf5610c467..cf89d8862f 100644 --- a/sysdeps/mach/hurd/lutimes.c +++ b/sysdeps/mach/hurd/lutimes.c @@ -1,5 +1,5 @@ /* lutimes -- change access and modification times of a symlink. Hurd version. - Copyright (C) 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2002 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 @@ -28,13 +28,7 @@ int __lutimes (const char *file, const struct timeval tvp[2]) { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - const union tv *u = (const union tv *) tvp; - union tv nulltv[2]; + struct timeval timevals[2]; error_t err; file_t port; @@ -42,14 +36,15 @@ __lutimes (const char *file, const struct timeval tvp[2]) { /* Setting the number of microseconds to `-1' tells the underlying filesystems to use the current time. */ - nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; - u = nulltv; + timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1; + tvp = timevals; } port = __file_name_lookup (file, O_NOLINK, 0); if (port == MACH_PORT_NULL) return -1; - err = __file_utimes (port, u[0].tvt, u[1].tvt); + err = __file_utimes (port, + *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]); __mach_port_deallocate (__mach_task_self (), port); if (err) return __hurd_fail (err); diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c index fdc1427feb..74f3a342f4 100644 --- a/sysdeps/mach/hurd/utimes.c +++ b/sysdeps/mach/hurd/utimes.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1991-1995,1997,1999,2000,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1991-1995, 97, 99, 2000 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 @@ -29,13 +28,7 @@ __utimes (file, tvp) const char *file; const struct timeval tvp[2]; { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - const union tv *u = (const union tv *) tvp; - union tv nulltv[2]; + struct timeval timevals[2]; error_t err; file_t port; @@ -43,17 +36,19 @@ __utimes (file, tvp) { /* Setting the number of microseconds to `-1' tells the underlying filesystems to use the current time. */ - nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; - u = nulltv; + timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1; + tvp = timevals; } port = __file_name_lookup (file, 0, 0); if (port == MACH_PORT_NULL) return -1; - err = __file_utimes (port, u[0].tvt, u[1].tvt); + err = __file_utimes (port, + *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]); __mach_port_deallocate (__mach_task_self (), port); if (err) return __hurd_fail (err); return 0; } + weak_alias (__utimes, utimes) diff --git a/sysdeps/posix/euidaccess.c b/sysdeps/posix/euidaccess.c index 76a09d455d..333870cdde 100644 --- a/sysdeps/posix/euidaccess.c +++ b/sysdeps/posix/euidaccess.c @@ -1,5 +1,5 @@ /* Check if effective user id can access file - Copyright (C) 1990,1991,1995-2001,2005 Free Software Foundation, Inc. + Copyright (C) 1990,1991,1995-2001,2005,2007 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 @@ -128,10 +128,6 @@ euidaccess (path, mode) #ifdef _LIBC uid_t euid; gid_t egid; - - if (! __libc_enable_secure) - /* If we are not set-uid or set-gid, access does the same. */ - return __access (path, mode); #else if (have_ids == 0) { @@ -162,6 +158,10 @@ euidaccess (path, mode) /* Now we need the IDs. */ euid = __geteuid (); egid = __getegid (); + + if (__getuid () == euid && __getgid () == egid) + /* If we are not set-uid or set-gid, access does the same. */ + return __access (path, mode); #endif /* The super-user can read and write any file, and execute any file diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index b4966852a7..a7e1459c9c 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -1157,7 +1157,7 @@ get_scope (const struct sockaddr_storage *ss) 169.254/16 and 127/8 are link-local. */ if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127) scope = 2; - else if (addr[0] == 10 || (addr[0] == 172 && addr[1] == 16) + else if (addr[0] == 10 || (addr[0] == 172 && (addr[1] & 0xf0) == 16) || (addr[0] == 192 && addr[1] == 168)) scope = 5; else @@ -1218,6 +1218,10 @@ static const struct prefixentry default_labels[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 7, 6 }, { { .in6_u + = { .u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 32, 7 }, + { { .in6_u = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 0, 1 } @@ -2085,12 +2089,10 @@ getaddrinfo (const char *name, const char *service, if (q->ai_family == PF_INET6 && in6ai != NULL) { - /* See whether the source address is the list of - deprecated or temporary addresses. */ + /* See whether the address is the list of deprecated + or temporary addresses. */ struct in6addrinfo tmp; - struct sockaddr_in6 *sin6p - = (struct sockaddr_in6 *) &results[i].source_addr; - memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ); + memcpy (tmp.addr, q->ai_addr, IN6ADDRSZ); struct in6addrinfo *found = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai), diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h index 04478309d9..aed899e882 100644 --- a/sysdeps/powerpc/fpu/bits/mathinline.h +++ b/sysdeps/powerpc/fpu/bits/mathinline.h @@ -121,4 +121,62 @@ __NTH (fdimf (float __x, float __y)) #endif /* __USE_ISOC99 */ #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */ + +/* This code is used internally in the GNU libc. */ +#ifdef __LIBC_INTERNAL_MATH_INLINES + +#include <sysdep.h> +#include <ldsodefs.h> +#include <dl-procinfo.h> + +# if __WORDSIZE == 64 || defined _ARCH_PWR4 +# define __CPU_HAS_FSQRT 1 +# else +# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) +# endif + +extern double __slow_ieee754_sqrt (double); +__MATH_INLINE double +__NTH (__ieee754_sqrt (double __x)) +{ + double __z; + + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) + { + /* Volatile is required to prevent the compiler from moving the + fsqrt instruction above the branch. */ + __asm __volatile ( + " fsqrt %0,%1\n" + : "=f" (__z) + : "f" (__x)); + } + else + __z = __slow_ieee754_sqrt(__x); + + return __z; +} + +extern float __slow_ieee754_sqrtf (float); +__MATH_INLINE float +__NTH (__ieee754_sqrtf (float __x)) +{ + float __z; + + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) + { + /* Volatile is required to prevent the compiler from moving the + fsqrts instruction above the branch. */ + __asm __volatile ( + " fsqrts %0,%1\n" + : "=f" (__z) + : "f" (__x)); + } + else + __z = __slow_ieee754_sqrtf(__x); + + return __z; +} +#endif /* __LIBC_INTERNAL_MATH_INLINES */ #endif /* __GNUC__ && !_SOFT_FLOAT */ diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h deleted file mode 100644 index 90021c6d3c..0000000000 --- a/sysdeps/powerpc/fpu/math_private.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Private inline math functions for powerpc. - Copyright (C) 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., 51 Franklin St - Fifth Floor, Boston, - MA 02110-1301 USA */ - -#ifndef _PPC_MATH_PRIVATE_H_ -#define _PPC_MATH_PRIVATE_H_ - -#include <sysdep.h> -#include <ldsodefs.h> -#include <dl-procinfo.h> - -# if __WORDSIZE == 64 || defined _ARCH_PWR4 -# define __CPU_HAS_FSQRT 1 -# else -# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) -# endif - -# ifndef __LIBC_INTERNAL_MATH_INLINES -extern double __slow_ieee754_sqrt (double); -__inline double -__ieee754_sqrt (double __x) -{ - double __z; - - /* If the CPU is 64-bit we can use the optional FP instructions. */ - if (__CPU_HAS_FSQRT) - { - /* Volatile is required to prevent the compiler from moving the - fsqrt instruction above the branch. */ - __asm __volatile ( - " fsqrt %0,%1\n" - : "=f" (__z) - : "f" (__x)); - } - else - __z = __slow_ieee754_sqrt(__x); - - return __z; -} - -extern float __slow_ieee754_sqrtf (float); - -__inline float -__ieee754_sqrtf (float __x) -{ - float __z; - - /* If the CPU is 64-bit we can use the optional FP instructions. */ - if (__CPU_HAS_FSQRT) - { - /* Volatile is required to prevent the compiler from moving the - fsqrts instruction above the branch. */ - __asm __volatile ( - " fsqrts %0,%1\n" - : "=f" (__z) - : "f" (__x)); - } - else - __z = __slow_ieee754_sqrtf(__x); - - return __z; -} -#endif /* __LIBC_INTERNAL_MATH_INLINES */ - -#include <math/math_private.h> - -#endif /* _PPC_MATH_PRIVATE_H_ */ diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c index fc460993b1..4120a02382 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.c +++ b/sysdeps/powerpc/powerpc32/dl-machine.c @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation functions. PowerPC version. - Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -564,12 +564,13 @@ __process_machine_rela (struct link_map *map, } break; +#ifdef USE_TLS #define CHECK_STATIC_TLS(map, sym_map) \ do { \ if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0)) \ _dl_allocate_static_tls (sym_map); \ } while (0) -#define DO_TLS_RELOC(suffix) \ +# define DO_TLS_RELOC(suffix) \ case R_PPC_DTPREL##suffix: \ /* During relocation all TLS symbols are defined and used. \ Therefore the offset is already correct. */ \ @@ -608,6 +609,7 @@ __process_machine_rela (struct link_map *map, DO_TLS_RELOC (16_LO) DO_TLS_RELOC (16_HI) DO_TLS_RELOC (16_HA) +#endif default: _dl_reloc_bad_type (map, rinfo, 0); diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h index a50ffdd1c2..496fa71ecc 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.h +++ b/sysdeps/powerpc/powerpc32/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. PowerPC version. - Copyright (C) 1995-2002, 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -138,7 +138,7 @@ __elf_preferred_address(struct link_map *loader, size_t maplength, /* We never want to use a PLT entry as the destination of a reloc, when what is being relocated is a branch. This is partly for efficiency, but mostly so we avoid loops. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) #define elf_machine_type_class(type) \ ((((type) == R_PPC_JMP_SLOT \ || (type) == R_PPC_REL24 \ @@ -330,7 +330,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = value; break; -#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP # ifdef RTLD_BOOTSTRAP # define NOT_BOOTSTRAP 0 @@ -361,7 +361,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc); } break; -#endif +#endif /* USE_TLS etc. */ case R_PPC_JMP_SLOT: #ifdef RESOLVE_CONFLICT_FIND_MAP diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 88cfe71e0b..8fc624ebd9 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -96,7 +96,7 @@ #endif #if defined SHARED && defined DO_VERSIONING && defined PIC \ - && !defined NO_HIDDEN + && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE && !defined NO_HIDDEN # undef HIDDEN_JUMPTARGET # define HIDDEN_JUMPTARGET(name) __GI_##name##@local #endif diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index 89a69e1a23..cec271bb3a 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -1,6 +1,7 @@ /* Machine-dependent ELF dynamic relocation inline functions. PowerPC64 version. - Copyright 1995-2005, 2006 Free Software Foundation, Inc. + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -259,7 +260,7 @@ BODY_PREFIX "_dl_start_user:\n" \ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) #define elf_machine_type_class(type) \ /* This covers all the TLS relocs, though most won't appear. */ \ (((((type) >= R_PPC64_DTPMOD64 && (type) <= R_PPC64_TPREL16_HIGHESTA) \ @@ -494,7 +495,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, *reloc_addr = l_addr + reloc->r_addend; } -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) /* This computes the value used by TPREL* relocs. */ auto inline Elf64_Addr __attribute__ ((always_inline, const)) elf_machine_tprel (struct link_map *map, @@ -561,7 +562,7 @@ elf_machine_rela (struct link_map *map, #endif return; -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) case R_PPC64_DTPMOD64: # ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always index 1. */ @@ -644,7 +645,7 @@ elf_machine_rela (struct link_map *map, value = elf_machine_tprel (map, sym_map, sym, reloc); *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value); break; -#endif +#endif /* USE_TLS etc. */ #ifndef RTLD_BOOTSTRAP /* None of the following appear in ld.so */ case R_PPC64_ADDR16_LO_DS: diff --git a/sysdeps/s390/libc-tls.c b/sysdeps/s390/libc-tls.c index 766d565a9c..f177f436e9 100644 --- a/sysdeps/s390/libc-tls.c +++ b/sysdeps/s390/libc-tls.c @@ -1,5 +1,5 @@ /* Thread-local storage handling in the ELF dynamic linker. S390 version. - Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,9 +20,11 @@ #include <stdlib.h> #include <csu/libc-tls.c> +#if USE_TLS + /* On s390, the literal pool entry that refers to __tls_get_offset is not removed, even if all branches that use the literal pool - entry gets removed by TLS optimizations. To get binaries + entry gets removed by TLS optimizations. To get binaries statically linked __tls_get_offset is defined here but aborts if it is used. */ @@ -31,3 +33,5 @@ __tls_get_offset (size_t m, size_t offset) { abort (); } + +#endif diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 64bf3423b6..8bbf858fbf 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. S390 Version. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Carl Pederson & Martin Schwidefsky. This file is part of the GNU C Library. @@ -209,11 +209,17 @@ _dl_start_user:\n\ define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ +#ifdef USE_TLS +# define elf_machine_type_class(type) \ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \ * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#else +# define elf_machine_type_class(type) \ + ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT @@ -309,7 +315,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = value + reloc->r_addend; break; -#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP case R_390_TLS_DTPMOD: # ifdef RTLD_BOOTSTRAP diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index fa893befdf..5026a2edad 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. 64 bit S/390 Version. - Copyright (C) 2001-2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -192,11 +192,17 @@ _dl_start_user:\n\ define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ +#ifdef USE_TLS +# define elf_machine_type_class(type) \ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \ * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#else +# define elf_machine_type_class(type) \ + ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT @@ -288,7 +294,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, *reloc_addr = value + reloc->r_addend; break; -#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP case R_390_TLS_DTPMOD: # ifdef RTLD_BOOTSTRAP diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h index 78f70e3880..e73c6d79c3 100644 --- a/sysdeps/sh/dl-machine.h +++ b/sysdeps/sh/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. SH version. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -208,7 +208,7 @@ __fpscr_values:\n\ define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) # define elf_machine_type_class(type) \ ((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32 \ || (type) == R_SH_TLS_DTPOFF32 || (type) == R_SH_TLS_TPOFF32) \ @@ -354,7 +354,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, /* These addresses are always aligned. */ *reloc_addr = value; break; -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) /* XXX Remove TLS relocations which are not needed. */ case R_SH_TLS_DTPMOD32: # ifdef RTLD_BOOTSTRAP diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index 19aac6a7fe..02dabaabb4 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -188,7 +188,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) # define elf_machine_type_class(type) \ ((((type) == R_SPARC_JMP_SLOT \ || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \ @@ -459,7 +459,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, so we can optimize the first instruction of .plt out. */ sparc_fixup_plt (reloc, reloc_addr, value, 0); break; -#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP case R_SPARC_TLS_DTPMOD32: /* Get the information from the link map returned by the diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index 3eee672912..314a784dbc 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -240,7 +240,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) # define elf_machine_type_class(type) \ ((((type) == R_SPARC_JMP_SLOT \ || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \ @@ -589,7 +589,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0); #endif break; -#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP case R_SPARC_TLS_DTPMOD64: /* Get the information from the link map returned by the diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 137b44c2b8..7c015b1d62 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -126,9 +126,6 @@ libc { GLIBC_2.5 { splice; sync_file_range; tee; vmsplice; } - GLIBC_2.6 { - epoll_pwait; - } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/bits/statvfs.h b/sysdeps/unix/sysv/linux/bits/statvfs.h index 84717c3d96..cca0871ac0 100644 --- a/sysdeps/unix/sysv/linux/bits/statvfs.h +++ b/sysdeps/unix/sysv/linux/bits/statvfs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997,1998,2000,2001,2002,2006 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 2000, 2001, 2002 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 @@ -101,9 +101,7 @@ enum # define ST_IMMUTABLE ST_IMMUTABLE ST_NOATIME = 1024, /* Do not update access times. */ # define ST_NOATIME ST_NOATIME - ST_NODIRATIME = 2048, /* Do not update directory access times. */ + ST_NODIRATIME = 2048 /* Do not update directory access times. */ # define ST_NODIRATIME ST_NODIRATIME - ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */ -# define ST_RELATIME ST_RELATIME #endif /* Use GNU. */ }; diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c index 13ccd7acb4..46161a806a 100644 --- a/sysdeps/unix/sysv/linux/check_pf.c +++ b/sysdeps/unix/sysv/linux/check_pf.c @@ -1,5 +1,5 @@ /* Determine protocol families for which interfaces exist. Linux version. - Copyright (C) 2003, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2007 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 @@ -71,17 +71,38 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, memset (&nladdr, '\0', sizeof (nladdr)); nladdr.nl_family = AF_NETLINK; +#ifdef PAGE_SIZE + /* Help the compiler optimize out the malloc call if PAGE_SIZE + is constant and smaller or equal to PTHREAD_STACK_MIN/4. */ + const size_t buf_size = PAGE_SIZE; +#else + const size_t buf_size = __getpagesize (); +#endif + bool use_malloc = false; + char *buf; + + if (__libc_use_alloca (buf_size)) + buf = alloca (buf_size); + else + { + buf = malloc (buf_size); + if (buf != NULL) + use_malloc = true; + else + goto out_fail; + } + + struct iovec iov = { buf, buf_size }; + if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0, (struct sockaddr *) &nladdr, sizeof (nladdr))) < 0) - return -1; + goto out_fail; *seen_ipv4 = false; *seen_ipv6 = false; bool done = false; - char buf[4096]; - struct iovec iov = { buf, sizeof (buf) }; struct in6ailist { struct in6addrinfo info; @@ -101,10 +122,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0)); if (read_len < 0) - return -1; + goto out_fail; if (msg.msg_flags & MSG_TRUNC) - return -1; + goto out_fail; struct nlmsghdr *nlmh; for (nlmh = (struct nlmsghdr *) buf; @@ -186,7 +207,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, { *in6ai = malloc (in6ailistlen * sizeof (**in6ai)); if (*in6ai == NULL) - return -1; + goto out_fail; *in6ailen = in6ailistlen; @@ -198,7 +219,14 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, while (in6ailist != NULL); } + if (use_malloc) + free (buf); return 0; + +out_fail: + if (use_malloc) + free (buf); + return -1; } diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S index f73a4b5195..54524ec120 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -120,9 +120,6 @@ L(pseudo_end): ret L(thread_start): - cfi_startproc; - /* Clearing frame pointer is insufficient, use CFI. */ - cfi_undefined (eip); /* Note: %esi is zero. */ movl %esi,%ebp /* terminate the stack frame */ #ifdef RESET_PID @@ -155,7 +152,6 @@ L(nomoregetpid): jmp L(haspid) .previous #endif - cfi_endproc; cfi_startproc PSEUDO_END (BP_SYM (__clone)) diff --git a/sysdeps/unix/sysv/linux/i386/getgroups.c b/sysdeps/unix/sysv/linux/i386/getgroups.c index f69baf943b..b7a0a4efd4 100644 --- a/sysdeps/unix/sysv/linux/i386/getgroups.c +++ b/sysdeps/unix/sysv/linux/i386/getgroups.c @@ -52,6 +52,8 @@ __getgroups (int n, gid_t *groups) } else { + int i, ngids; + __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))]; # ifdef __NR_getgroups32 if (__libc_missing_32bit_uids <= 0) { @@ -67,9 +69,6 @@ __getgroups (int n, gid_t *groups) } # endif /* __NR_getgroups32 */ - int i, ngids; - __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))]; - ngids = INLINE_SYSCALL (getgroups, 2, n, CHECK_N (kernel_groups, n)); if (n != 0 && ngids > 0) for (i = 0; i < ngids; i++) diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index b5c1b98573..299574dac4 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -1,5 +1,5 @@ /* POSIX.1 `sigaction' call for Linux/i386. - Copyright (C) 1991,1995-2000,2002-2005,2006 Free Software Foundation, Inc. + Copyright (C) 1991,1995-2000,2002-2004,2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -46,10 +46,18 @@ int __libc_missing_rt_sigs; /* Using the hidden attribute here does not change the code but it helps to avoid warnings. */ -#ifdef __NR_rt_sigaction +#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \ + && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE +# ifdef __NR_rt_sigaction extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; -#endif +# endif extern void restore (void) asm ("__restore") attribute_hidden; +#else +# ifdef __NR_rt_sigaction +static void restore_rt (void) asm ("__restore_rt"); +# endif +static void restore (void) asm ("__restore"); +#endif /* If ACT is not NULL, change the action for SIG to *ACT. diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index 82495de03e..02e6935538 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c +++ b/sysdeps/unix/sysv/linux/ifaddrs.c @@ -1,5 +1,5 @@ /* getifaddrs -- get names and addresses of all network interfaces - Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007 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 @@ -122,36 +122,36 @@ int __netlink_request (struct netlink_handle *h, int type) { struct netlink_res *nlm_next; - struct netlink_res **new_nlm_list; - static volatile size_t buf_size = 4096; - char *buf; struct sockaddr_nl nladdr; struct nlmsghdr *nlmh; ssize_t read_len; bool done = false; - bool use_malloc = false; - if (__netlink_sendreq (h, type) < 0) - return -1; +#ifdef PAGE_SIZE + /* Help the compiler optimize out the malloc call if PAGE_SIZE + is constant and smaller or equal to PTHREAD_STACK_MIN/4. */ + const size_t buf_size = PAGE_SIZE; +#else + const size_t buf_size = __getpagesize (); +#endif + bool use_malloc = false; + char *buf; - size_t this_buf_size = buf_size; - if (__libc_use_alloca (this_buf_size)) - buf = alloca (this_buf_size); + if (__libc_use_alloca (buf_size)) + buf = alloca (buf_size); else { - buf = malloc (this_buf_size); + buf = malloc (buf_size); if (buf != NULL) use_malloc = true; else goto out_fail; } - struct iovec iov = { buf, this_buf_size }; + struct iovec iov = { buf, buf_size }; - if (h->nlm_list != NULL) - new_nlm_list = &h->end_ptr->next; - else - new_nlm_list = &h->nlm_list; + if (__netlink_sendreq (h, type) < 0) + goto out_fail; while (! done) { @@ -171,48 +171,7 @@ __netlink_request (struct netlink_handle *h, int type) continue; if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0)) - { - if (this_buf_size >= SIZE_MAX / 2) - goto out_fail; - - nlm_next = *new_nlm_list; - while (nlm_next != NULL) - { - struct netlink_res *tmpptr; - - tmpptr = nlm_next->next; - free (nlm_next); - nlm_next = tmpptr; - } - *new_nlm_list = NULL; - - if (__libc_use_alloca (2 * this_buf_size)) - buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size); - else - { - this_buf_size *= 2; - - char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size); - if (new_buf == NULL) - goto out_fail; - new_buf = buf; - - use_malloc = true; - } - buf_size = this_buf_size; - - iov.iov_base = buf; - iov.iov_len = this_buf_size; - - /* Increase sequence number, so that we can distinguish - between old and new request messages. */ - h->seq++; - - if (__netlink_sendreq (h, type) < 0) - goto out_fail; - - continue; - } + goto out_fail; size_t count = 0; size_t remaining_len = read_len; diff --git a/sysdeps/unix/sysv/linux/internal_statvfs.c b/sysdeps/unix/sysv/linux/internal_statvfs.c index 28c1cb691f..73317ecafd 100644 --- a/sysdeps/unix/sysv/linux/internal_statvfs.c +++ b/sysdeps/unix/sysv/linux/internal_statvfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -156,8 +156,6 @@ __statvfs_getflags (const char *name, int fstype, struct stat64 *st) result |= ST_NOATIME; else if (strcmp (opt, "nodiratime") == 0) result |= ST_NODIRATIME; - else if (strcmp (opt, "relatime") == 0) - result |= ST_RELATIME; /* We can stop looking for more entries. */ success = true; diff --git a/sysdeps/unix/sysv/linux/posix_madvise.c b/sysdeps/unix/sysv/linux/posix_madvise.c new file mode 100644 index 0000000000..880b17ef31 --- /dev/null +++ b/sysdeps/unix/sysv/linux/posix_madvise.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2007 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 <sys/mman.h> + + +int +posix_madvise (void *addr, size_t len, int advice) +{ + /* We have one problem: the kernel's MADV_DONTNEED does not + correspond to POSIX's POSIX_MADV_DONTNEED. The former simply + discards changes made to the memory without writing it back to + disk, if this would be necessary. The POSIX behavior does not + allow this. There is no functionality mapping the POSIX behavior + so far so we ignore that advice for now. */ + if (advice == POSIX_MADV_DONTNEED) + return 0; + + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (madvise, err, 3, addr, len, advice); + return INTERNAL_SYSCALL_ERRNO (result, err); +} diff --git a/sysdeps/unix/sysv/linux/sh/bits/shm.h b/sysdeps/unix/sysv/linux/sh/bits/shm.h deleted file mode 100644 index 189179394b..0000000000 --- a/sysdeps/unix/sysv/linux/sh/bits/shm.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 1995,1996,1997,2000,2002,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. */ - -#ifndef _SYS_SHM_H -# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." -#endif - -#include <bits/types.h> - -/* Permission flag for shmget. */ -#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ -#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ - -/* Flags for `shmat'. */ -#define SHM_RDONLY 010000 /* attach read-only else read-write */ -#define SHM_RND 020000 /* round attach address to SHMLBA */ -#define SHM_REMAP 040000 /* take-over region on attach */ - -/* Commands for `shmctl'. */ -#define SHM_LOCK 11 /* lock segment (root only) */ -#define SHM_UNLOCK 12 /* unlock segment (root only) */ - -__BEGIN_DECLS - -/* Segment low boundary address multiple. */ -#define SHMLBA 0x4000 - -/* Type to count number of attaches. */ -typedef unsigned long int shmatt_t; - -/* Data structure describing a set of semaphores. */ -struct shmid_ds - { - struct ipc_perm shm_perm; /* operation permission struct */ - size_t shm_segsz; /* size of segment in bytes */ - __time_t shm_atime; /* time of last shmat() */ - unsigned long int __unused1; - __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __unused2; - __time_t shm_ctime; /* time of last change by shmctl() */ - unsigned long int __unused3; - __pid_t shm_cpid; /* pid of creator */ - __pid_t shm_lpid; /* pid of last shmop */ - shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __unused4; - unsigned long int __unused5; - }; - -#ifdef __USE_MISC - -/* ipcs ctl commands */ -# define SHM_STAT 13 -# define SHM_INFO 14 - -/* shm_mode upper byte flags */ -# define SHM_DEST 01000 /* segment will be destroyed on last detach */ -# define SHM_LOCKED 02000 /* segment will not be swapped */ -# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ -# define SHM_NORESERVE 010000 /* don't check for reservations */ - -struct shminfo - { - unsigned long int shmmax; - unsigned long int shmmin; - unsigned long int shmmni; - unsigned long int shmseg; - unsigned long int shmall; - unsigned long int __unused1; - unsigned long int __unused2; - unsigned long int __unused3; - unsigned long int __unused4; - }; - -struct shm_info - { - int used_ids; - unsigned long int shm_tot; /* total allocated shm */ - unsigned long int shm_rss; /* total resident shm */ - unsigned long int shm_swp; /* total swapped shm */ - unsigned long int swap_attempts; - unsigned long int swap_successes; - }; - -#endif /* __USE_MISC */ - -__END_DECLS diff --git a/sysdeps/unix/sysv/linux/sh/sys/io.h b/sysdeps/unix/sysv/linux/sh/sys/io.h new file mode 100644 index 0000000000..6fdc44ff89 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sys/io.h @@ -0,0 +1,48 @@ +/* Copyright (C) 1996, 1998, 1999, 2000 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. */ + +#ifndef _SYS_IO_H + +#define _SYS_IO_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* If TURN_ON is TRUE, request for permission to do direct i/o on the + port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O + permission off for that range. This call requires root privileges. */ +extern int ioperm (unsigned long int __from, unsigned long int __num, + int __turn_on) __THROW; + +/* Set the I/O privilege level to LEVEL. If LEVEL is nonzero, + permission to access any I/O port is granted. This call requires + root privileges. */ +extern int iopl (int __level) __THROW; + +/* The functions that actually perform reads and writes. */ +extern unsigned char inb (unsigned long int port) __THROW; +extern unsigned short int inw (unsigned long int port) __THROW; +extern unsigned long int inl (unsigned long int port) __THROW; + +extern void outb (unsigned char value, unsigned long int port) __THROW; +extern void outw (unsigned short value, unsigned long int port) __THROW; +extern void outl (unsigned long value, unsigned long int port) __THROW; + +__END_DECLS + +#endif /* _SYS_IO_H */ diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h index d8901f7d53..68f173a04d 100644 --- a/sysdeps/unix/sysv/linux/sys/epoll.h +++ b/sysdeps/unix/sysv/linux/sys/epoll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,14 +22,6 @@ #include <stdint.h> #include <sys/types.h> -/* Get __sigset_t. */ -#include <bits/sigset.h> - -#ifndef __sigset_t_defined -# define __sigset_t_defined -typedef __sigset_t sigset_t; -#endif - enum EPOLL_EVENTS { @@ -113,16 +105,6 @@ extern int epoll_ctl (int __epfd, int __op, int __fd, extern int epoll_wait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout); - -/* Same as epoll_wait, but the thread's signal mask is temporarily - and atomically replaced with the one provided as parameter. - - This function is a cancellation point and therefore not marked with - __THROW. */ -extern int epoll_pwait (int __epfd, struct epoll_event *__events, - int __maxevents, int __timeout, - __const __sigset_t *__ss); - __END_DECLS #endif /* sys/epoll.h */ diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 5776673733..e16110480f 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -10,8 +10,7 @@ delete_module EXTRA delete_module 3 delete_module epoll_create EXTRA epoll_create i:i epoll_create epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait -epoll_pwait EXTRA epoll_pwait Ci:ipiipi epoll_pwait -fdatasync - fdatasync i:i fdatasync +fdatasync - fdatasync Ci:i fdatasync flock - flock i:ii __flock flock fork - fork i: __libc_fork __fork fork get_kernel_syms EXTRA get_kernel_syms i:p get_kernel_syms @@ -32,7 +31,6 @@ ioperm - ioperm i:iii ioperm iopl - iopl i:i iopl klogctl EXTRA syslog i:isi klogctl lchown - lchown i:sii __lchown lchown -posix_madvise - madvise Vi:pii posix_madvise madvise - madvise i:pii madvise mincore - mincore i:anV mincore mlock - mlock i:bn mlock diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile index bdad5063df..0f20367236 100644 --- a/sysdeps/unix/sysv/linux/x86_64/Makefile +++ b/sysdeps/unix/sysv/linux/x86_64/Makefile @@ -10,6 +10,6 @@ ifeq ($(subdir),stdlib) sysdep_routines += __start_context endif -ifeq ($(subdir),csu) +ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym endif diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S index db42f209c9..8a12b09035 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -89,9 +89,6 @@ L(pseudo_end): ret L(thread_start): - cfi_startproc; - /* Clearing frame pointer is insufficient, use CFI. */ - cfi_undefined (rip); /* Clear the frame pointer. The ABI suggests this be done, to mark the outermost frame obviously. */ xorl %ebp, %ebp @@ -116,7 +113,6 @@ L(thread_start): /* Call exit with return value from function call. */ movq %rax, %rdi call HIDDEN_JUMPTARGET (_exit) - cfi_endproc; cfi_startproc; PSEUDO_END (BP_SYM (__clone)) diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index ab10123858..d6f4558cef 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -1,5 +1,5 @@ /* POSIX.1 `sigaction' call for Linux/x86-64. - Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,14 +33,17 @@ translate it here. */ #include <kernel_sigaction.h> -#include "ucontext_i.h" - /* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 /* Using the hidden attribute here does not change the code but it helps to avoid warnings. */ +#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \ + && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; +#else +static void restore_rt (void) asm ("__restore_rt"); +#endif /* If ACT is not NULL, change the action for SIG to *ACT. @@ -92,95 +95,18 @@ weak_alias (__libc_sigaction, sigaction) signal handlers work right. Important are both the names (__restore_rt) and the exact instruction sequence. If you ever feel the need to make any changes, please notify the - appropriate GDB maintainer. - - The unwind information starts a byte before __restore_rt, so that - it is found when unwinding, to get an address the unwinder assumes - will be in the middle of a call instruction. See the Linux kernel - (the i386 vsyscall, in particular) for an explanation of the complex - unwind information used here in order to get the traditional CFA. - We do not restore cs - it's only stored as two bytes here so that's - a bit tricky. We don't use the gas cfi directives, so that we can - reliably add .cfi_signal_frame. */ - -#define do_cfa_expr \ - " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ - " .uleb128 2f-1f\n" /* length */ \ - "1: .byte 0x77\n" /* DW_OP_breg7 */ \ - " .sleb128 " CFI_STRINGIFY (oRSP) "\n" \ - " .byte 0x06\n" /* DW_OP_deref */ \ - "2:" - -#define do_expr(regno, offset) \ - " .byte 0x10\n" /* DW_CFA_expression */ \ - " .uleb128 " CFI_STRINGIFY (regno) "\n" \ - " .uleb128 2f-1f\n" /* length */ \ - "1: .byte 0x77\n" /* DW_OP_breg7 */ \ - " .sleb128 " CFI_STRINGIFY (offset) "\n" \ - "2:" + appropriate GDB maintainer. */ #define RESTORE(name, syscall) RESTORE2 (name, syscall) # define RESTORE2(name, syscall) \ -asm \ - ( \ - /* `nop' for debuggers assuming `call' should not disalign the code. */ \ - " nop\n" \ - ".align 16\n" \ - ".LSTART_" #name ":\n" \ - " .type __" #name ",@function\n" \ - "__" #name ":\n" \ - " movq $" #syscall ", %rax\n" \ - " syscall\n" \ - ".LEND_" #name ":\n" \ - ".section .eh_frame,\"a\",@progbits\n" \ - ".LSTARTFRAME_" #name ":\n" \ - " .long .LENDCIE_" #name "-.LSTARTCIE_" #name "\n" \ - ".LSTARTCIE_" #name ":\n" \ - " .long 0\n" /* CIE ID */ \ - " .byte 1\n" /* Version number */ \ - " .string \"zRS\"\n" /* NUL-terminated augmentation string */ \ - " .uleb128 1\n" /* Code alignment factor */ \ - " .sleb128 -8\n" /* Data alignment factor */ \ - " .uleb128 16\n" /* Return address register column (rip) */ \ - /* Augmentation value length */ \ - " .uleb128 .LENDAUGMNT_" #name "-.LSTARTAUGMNT_" #name "\n" \ - ".LSTARTAUGMNT_" #name ":\n" \ - " .byte 0x1b\n" /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ \ - ".LENDAUGMNT_" #name ":\n" \ - " .align 8\n" \ - ".LENDCIE_" #name ":\n" \ - " .long .LENDFDE_" #name "-.LSTARTFDE_" #name "\n" /* FDE len */ \ - ".LSTARTFDE_" #name ":\n" \ - " .long .LSTARTFDE_" #name "-.LSTARTFRAME_" #name "\n" /* CIE */ \ - /* `LSTART_' is subtracted 1 as debuggers assume a `call' here. */ \ - " .long (.LSTART_" #name "-1)-.\n" /* PC-relative start addr. */ \ - " .long .LEND_" #name "-(.LSTART_" #name "-1)\n" \ - " .uleb128 0\n" /* FDE augmentation length */ \ - do_cfa_expr \ - do_expr (8 /* r8 */, oR8) \ - do_expr (9 /* r9 */, oR9) \ - do_expr (10 /* r10 */, oR10) \ - do_expr (11 /* r11 */, oR11) \ - do_expr (12 /* r12 */, oR12) \ - do_expr (13 /* r13 */, oR13) \ - do_expr (14 /* r14 */, oR14) \ - do_expr (15 /* r15 */, oR15) \ - do_expr (5 /* rdi */, oRDI) \ - do_expr (4 /* rsi */, oRSI) \ - do_expr (6 /* rbp */, oRBP) \ - do_expr (3 /* rbx */, oRBX) \ - do_expr (1 /* rdx */, oRDX) \ - do_expr (0 /* rax */, oRAX) \ - do_expr (2 /* rcx */, oRCX) \ - do_expr (7 /* rsp */, oRSP) \ - do_expr (16 /* rip */, oRIP) \ - /* libgcc-4.1.1 has only `DWARF_FRAME_REGISTERS == 17'. */ \ - /* do_expr (49 |* rflags *|, oEFL) */ \ - /* `cs'/`ds'/`fs' are unaligned and a different size. */ \ - /* gas: Error: register save offset not a multiple of 8 */ \ - " .align 8\n" \ - ".LENDFDE_" #name ":\n" \ - " .previous\n" \ +asm \ + ( \ + ".align 16\n" \ + CFI_STARTPROC "\n" \ + "__" #name ":\n" \ + " movq $" #syscall ", %rax\n" \ + " syscall\n" \ + CFI_ENDPROC "\n" \ ); /* The return code for realtime-signals. */ RESTORE (restore_rt, __NR_rt_sigreturn) diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym index af3e0e544b..b3cfe9aa4c 100644 --- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym +++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym @@ -18,8 +18,6 @@ oRSP mreg (RSP) oRBX mreg (RBX) oR8 mreg (R8) oR9 mreg (R9) -oR10 mreg (R10) -oR11 mreg (R11) oR12 mreg (R12) oR13 mreg (R13) oR14 mreg (R14) @@ -30,7 +28,6 @@ oRDX mreg (RDX) oRAX mreg (RAX) oRCX mreg (RCX) oRIP mreg (RIP) -oEFL mreg (EFL) oFPREGS mcontext (fpregs) oSIGMASK ucontext (uc_sigmask) oFPREGSMEM ucontext (__fpregs_mem) diff --git a/sysdeps/x86_64/bits/atomic.h b/sysdeps/x86_64/bits/atomic.h index 65d6b02008..133a68d192 100644 --- a/sysdeps/x86_64/bits/atomic.h +++ b/sysdeps/x86_64/bits/atomic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -18,7 +18,6 @@ 02111-1307 USA. */ #include <stdint.h> -#include <tls.h> /* For tcbhead_t. */ typedef int8_t atomic8_t; @@ -81,54 +80,8 @@ typedef uintmax_t uatomic_max_t; ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1" \ : "=a" (ret), "=m" (*mem) \ - : "r" ((long int) (newval)), "m" (*mem), \ - "0" ((long int) (oldval))); \ - ret; }) - - -#define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgb %b2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "q" (newval), "m" (*mem), "0" (oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) - -#define __arch_c_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgw %w2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "q" (newval), "m" (*mem), "0" (oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) - -#define __arch_c_compare_and_exchange_val_32_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgl %2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "q" (newval), "m" (*mem), "0" (oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - ret; }) - -#define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - ({ __typeof (*mem) ret; \ - __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgq %q2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "q" ((long int) (newval)), "m" (*mem), \ - "0" ((long int)oldval), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "r" ((long) (newval)), "m" (*mem), \ + "0" ((long) (oldval))); \ ret; }) @@ -154,76 +107,49 @@ typedef uintmax_t uatomic_max_t; result; }) -#define __arch_exchange_and_add_body(lock, mem, value) \ +#define atomic_exchange_and_add(mem, value) \ ({ __typeof (*mem) result; \ if (sizeof (*mem) == 1) \ - __asm __volatile (lock "xaddb %b0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" (value), "m" (*mem)); \ else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "xaddw %w0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" (value), "m" (*mem)); \ else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "xaddl %0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" (value), "m" (*mem)); \ else \ - __asm __volatile (lock "xaddq %q0, %1" \ + __asm __volatile (LOCK_PREFIX "xaddq %q0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" ((long) (value)), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ + : "0" ((long) (value)), "m" (*mem)); \ result; }) -#define atomic_exchange_and_add(mem, value) \ - __arch_exchange_and_add_body (LOCK_PREFIX, mem, value) - -#define __arch_exchange_and_add_cprefix \ - "cmpl $0, %%fs:%P4\n\tje 0f\n\tlock\n0:\t" - -#define catomic_exchange_and_add(mem, value) \ - __arch_exchange_and_add_body (__arch_exchange_and_add_cprefix, mem, value) - - -#define __arch_add_body(lock, pfx, mem, value) \ - do { \ - if (__builtin_constant_p (value) && (value) == 1) \ - pfx##_increment (mem); \ - else if (__builtin_constant_p (value) && (value) == -1) \ - pfx##_decrement (mem); \ - else if (sizeof (*mem) == 1) \ - __asm __volatile (lock "addb %b1, %0" \ - : "=m" (*mem) \ - : "ir" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "addw %w1, %0" \ - : "=m" (*mem) \ - : "ir" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "addl %1, %0" \ - : "=m" (*mem) \ - : "ir" (value), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - __asm __volatile (lock "addq %q1, %0" \ - : "=m" (*mem) \ - : "ir" ((long) (value)), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - } while (0) #define atomic_add(mem, value) \ - __arch_add_body (LOCK_PREFIX, atomic, mem, value) - -#define __arch_add_cprefix \ - "cmpl $0, %%fs:%P3\n\tje 0f\n\tlock\n0:\t" - -#define catomic_add(mem, value) \ - __arch_add_body (__arch_add_cprefix, catomic, mem, value) + (void) ({ if (__builtin_constant_p (value) && (value) == 1) \ + atomic_increment (mem); \ + else if (__builtin_constant_p (value) && (value) == 1) \ + atomic_decrement (mem); \ + else if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "addb %b1, %0" \ + : "=m" (*mem) \ + : "ir" (value), "m" (*mem)); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "addw %w1, %0" \ + : "=m" (*mem) \ + : "ir" (value), "m" (*mem)); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "addl %1, %0" \ + : "=m" (*mem) \ + : "ir" (value), "m" (*mem)); \ + else \ + __asm __volatile (LOCK_PREFIX "addq %q1, %0" \ + : "=m" (*mem) \ + : "ir" ((long) (value)), "m" (*mem)); \ + }) #define atomic_add_negative(mem, value) \ @@ -268,37 +194,24 @@ typedef uintmax_t uatomic_max_t; __result; }) -#define __arch_increment_body(lock, mem) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (lock "incb %b0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "incw %w0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "incl %0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - __asm __volatile (lock "incq %q0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - } while (0) - -#define atomic_increment(mem) __arch_increment_body (LOCK_PREFIX, mem) - -#define __arch_increment_cprefix \ - "cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t" - -#define catomic_increment(mem) \ - __arch_increment_body (__arch_increment_cprefix, mem) +#define atomic_increment(mem) \ + (void) ({ if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "incb %b0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "incw %w0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "incl %0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else \ + __asm __volatile (LOCK_PREFIX "incq %q0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + }) #define atomic_increment_and_test(mem) \ @@ -322,37 +235,24 @@ typedef uintmax_t uatomic_max_t; __result; }) -#define __arch_decrement_body(lock, mem) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (lock "decb %b0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "decw %w0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "decl %0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - __asm __volatile (lock "decq %q0" \ - : "=m" (*mem) \ - : "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - } while (0) - -#define atomic_decrement(mem) __arch_decrement_body (LOCK_PREFIX, mem) - -#define __arch_decrement_cprefix \ - "cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t" - -#define catomic_decrement(mem) \ - __arch_decrement_body (__arch_decrement_cprefix, mem) +#define atomic_decrement(mem) \ + (void) ({ if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "decb %b0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "decw %w0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "decl %0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + else \ + __asm __volatile (LOCK_PREFIX "decq %q0" \ + : "=m" (*mem) \ + : "m" (*mem)); \ + }) #define atomic_decrement_and_test(mem) \ @@ -377,28 +277,27 @@ typedef uintmax_t uatomic_max_t; #define atomic_bit_set(mem, bit) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (LOCK_PREFIX "orb %b2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "ir" (1L << (bit))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (LOCK_PREFIX "orw %w2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "ir" (1L << (bit))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (LOCK_PREFIX "orl %2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "ir" (1L << (bit))); \ - else if (__builtin_constant_p (bit) && (bit) < 32) \ - __asm __volatile (LOCK_PREFIX "orq %2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "i" (1L << (bit))); \ - else \ - __asm __volatile (LOCK_PREFIX "orq %q2, %0" \ - : "=m" (*mem) \ - : "m" (*mem), "r" (1UL << (bit))); \ - } while (0) + (void) ({ if (sizeof (*mem) == 1) \ + __asm __volatile (LOCK_PREFIX "orb %b2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "ir" (1L << (bit))); \ + else if (sizeof (*mem) == 2) \ + __asm __volatile (LOCK_PREFIX "orw %w2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "ir" (1L << (bit))); \ + else if (sizeof (*mem) == 4) \ + __asm __volatile (LOCK_PREFIX "orl %2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "ir" (1L << (bit))); \ + else if (__builtin_constant_p (bit) && (bit) < 32) \ + __asm __volatile (LOCK_PREFIX "orq %2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "i" (1L << (bit))); \ + else \ + __asm __volatile (LOCK_PREFIX "orq %q2, %0" \ + : "=m" (*mem) \ + : "m" (*mem), "r" (1UL << (bit))); \ + }) #define atomic_bit_test_set(mem, bit) \ @@ -423,56 +322,3 @@ typedef uintmax_t uatomic_max_t; #define atomic_delay() asm ("rep; nop") - - -#define atomic_and(mem, mask) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (LOCK_PREFIX "andb %1, %b0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (LOCK_PREFIX "andw %1, %w0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (LOCK_PREFIX "andl %1, %0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - else \ - __asm __volatile (LOCK_PREFIX "andq %1, %q0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem)); \ - } while (0) - - -#define __arch_or_body(lock, mem, mask) \ - do { \ - if (sizeof (*mem) == 1) \ - __asm __volatile (lock "orb %1, %b0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 2) \ - __asm __volatile (lock "orw %1, %w0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else if (sizeof (*mem) == 4) \ - __asm __volatile (lock "orl %1, %0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - else \ - __asm __volatile (lock "orq %1, %q0" \ - : "=m" (*mem) \ - : "ir" (mask), "m" (*mem), \ - "i" (offsetof (tcbhead_t, multiple_threads))); \ - } while (0) - -#define atomic_or(mem, mask) __arch_or_body (LOCK_PREFIX, mem, mask) - -#define __arch_or_cprefix \ - "cmpl $0, %%fs:%P3\n\tje 0f\n\tlock\n0:\t" - -#define catomic_or(mem, mask) __arch_or_body (__arch_or_cprefix, mem, mask) diff --git a/sysdeps/x86_64/bits/byteswap.h b/sysdeps/x86_64/bits/byteswap.h index e1c861c75f..ec2b17889d 100644 --- a/sysdeps/x86_64/bits/byteswap.h +++ b/sysdeps/x86_64/bits/byteswap.h @@ -1,5 +1,6 @@ /* Macros to swap the order of bytes in integer values. - Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2000, 2002, 2003, 2007 + 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 @@ -59,7 +60,9 @@ # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \ || defined __pentiumpro__ || defined __pentium4__ \ || defined __k8__ || defined __athlon__ \ - || defined __k6__) + || defined __k6__ || defined __nocona__ \ + || defined __core2__ || defined __geode__ \ + || defined __amdfam10__) /* To swap the bytes in a word the i486 processors and up provide the `bswap' opcode. On i386 we have to use three instructions. */ # define __bswap_32(x) \ diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 31a7013d50..73e271775a 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. x86-64 version. - Copyright (C) 2001-2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>. @@ -190,7 +190,7 @@ _dl_start_user:\n\ define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#if !defined RTLD_BOOTSTRAP || USE___THREAD +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) # define elf_machine_type_class(type) \ ((((type) == R_X86_64_JUMP_SLOT \ || (type) == R_X86_64_DTPMOD64 \ @@ -300,7 +300,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, *reloc_addr = value + reloc->r_addend; break; -#ifndef RESOLVE_CONFLICT_FIND_MAP +#if defined USE_TLS && !defined RESOLVE_CONFLICT_FIND_MAP case R_X86_64_DTPMOD64: # ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module @@ -339,7 +339,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, - sym_map->l_tls_offset); } break; -#endif +#endif /* use TLS */ #ifndef RTLD_BOOTSTRAP case R_X86_64_64: diff --git a/sysdeps/x86_64/fpu/e_log10l.S b/sysdeps/x86_64/fpu/e_log10l.S index b4343bef45..633234b744 100644 --- a/sysdeps/x86_64/fpu/e_log10l.S +++ b/sysdeps/x86_64/fpu/e_log10l.S @@ -42,7 +42,7 @@ ENTRY(__ieee754_log10l) fxam fnstsw fld %st // x : x : log10(2) - andb $1,%ah + testb $1, %ah jnz 3f // in case x is NaN or ħInf 4: fsubl MO(one) // x-1 : x : log10(2) fld %st // x-1 : x-1 : x : log10(2) @@ -59,7 +59,8 @@ ENTRY(__ieee754_log10l) fyl2x // log10(x) ret -3: jp 4b // in case x is ħInf +3: testb $4, %ah + jnz 4b // in case x is ħInf fstp %st(1) fstp %st(1) ret diff --git a/sysdeps/x86_64/fpu/e_log2l.S b/sysdeps/x86_64/fpu/e_log2l.S index 7a89b94d9f..f04d30a05a 100644 --- a/sysdeps/x86_64/fpu/e_log2l.S +++ b/sysdeps/x86_64/fpu/e_log2l.S @@ -39,7 +39,7 @@ ENTRY(__ieee754_log2l) fxam fnstsw fld %st // x : x : 1 - andb $1,%ah + testb $1, %ah jnz 3f // in case x is NaN or ħInf 4: fsub %st(2), %st // x-1 : x : 1 fld %st // x-1 : x-1 : x : 1 @@ -56,7 +56,8 @@ ENTRY(__ieee754_log2l) fyl2x // log(x) ret -3: jp 4b // in case x is ħInf +3: testb $4, %ah + jnz 4b // in case x is ħInf fstp %st(1) fstp %st(1) ret diff --git a/sysdeps/x86_64/fpu/e_logl.S b/sysdeps/x86_64/fpu/e_logl.S index a0bed663c8..2ba91eedfd 100644 --- a/sysdeps/x86_64/fpu/e_logl.S +++ b/sysdeps/x86_64/fpu/e_logl.S @@ -38,8 +38,12 @@ limit: .double 0.29 ENTRY(__ieee754_logl) fldln2 // log(2) fldt 8(%rsp) // x : log(2) + fxam + fnstsw fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + testb $1, %ah + jnz 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -53,4 +57,10 @@ ENTRY(__ieee754_logl) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: testb $4, %ah + jnz 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_logl) diff --git a/sysdeps/x86_64/fpu/e_powl.S b/sysdeps/x86_64/fpu/e_powl.S index 85f4deb3c7..4959bea7ac 100644 --- a/sysdeps/x86_64/fpu/e_powl.S +++ b/sysdeps/x86_64/fpu/e_powl.S @@ -1,5 +1,6 @@ /* ix87 specific implementation of pow function. - Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -146,10 +147,11 @@ ENTRY(__ieee754_powl) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 1.0 : x : y - fld %st(1) // x : 1.0 : x : y - fsub %st(1) // x-1 : 1.0 : x : y - fabs // |x-1| : 1.0 : x : y - fcompl MO(limit) // 1.0 : x : y + fldl MO(limit) // 0.29 : 1.0 : x : y + fld %st(2) // x : 0.29 : 1.0 : x : y + fsub %st(2) // x-1 : 0.29 : 1.0 : x : y + fabs // |x-1| : 0.29 : 1.0 : x : y + fucompp // 1.0 : x : y fnstsw fxch // x : 1.0 : y test $4500,%eax @@ -190,9 +192,10 @@ ENTRY(__ieee754_powl) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldt 8(%rsp) // x - fabs - fcompl MO(one) // < 1, == 1, or > 1 + fldl MO(one) // 1 + fldt 8(%rsp) // x : 1 + fabs // abs(x) : 1 + fucompp // < 1, == 1, or > 1 fnstsw andb $0x45, %ah cmpb $0x45, %ah diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h new file mode 100644 index 0000000000..4febcbb5ec --- /dev/null +++ b/sysdeps/x86_64/fpu/math_private.h @@ -0,0 +1,21 @@ +#ifndef _MATH_PRIVATE_H + +#define math_opt_barrier(x) \ +({ __typeof(x) __x; \ + if (sizeof (x) <= sizeof (double)) \ + __asm ("" : "=x" (__x) : "0" (x)); \ + else \ + __asm ("" : "=t" (__x) : "0" (x)); \ + __x; }) +#define math_force_eval(x) \ +do \ + { \ + if (sizeof (x) <= sizeof (double)) \ + __asm __volatile ("" : : "x" (x)); \ + else \ + __asm __volatile ("" : : "f" (x)); \ + } \ +while (0) + +#include <math/math_private.h> +#endif diff --git a/sysdeps/x86_64/fpu/s_copysign.S b/sysdeps/x86_64/fpu/s_copysign.S index f3d9b0cbb4..f1ebcf8bf1 100644 --- a/sysdeps/x86_64/fpu/s_copysign.S +++ b/sysdeps/x86_64/fpu/s_copysign.S @@ -1,5 +1,5 @@ /* copy sign, double version. - Copyright (C) 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2002. @@ -31,8 +31,6 @@ signmask: .byte 0, 0, 0, 0, 0, 0, 0, 0x80 .byte 0, 0, 0, 0, 0, 0, 0, 0 - ASM_SIZE_DIRECTIVE(signmask) - ASM_TYPE_DIRECTIVE(othermask,@object) othermask: .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f .byte 0, 0, 0, 0, 0, 0, 0, 0 @@ -44,7 +42,6 @@ othermask: #define MO(op) op #endif - .text ENTRY(__copysign) andpd MO(othermask),%xmm0 andpd MO(signmask),%xmm1 diff --git a/sysdeps/x86_64/fpu/s_copysignf.S b/sysdeps/x86_64/fpu/s_copysignf.S index 0fbe1d4c96..f5dc5f78ad 100644 --- a/sysdeps/x86_64/fpu/s_copysignf.S +++ b/sysdeps/x86_64/fpu/s_copysignf.S @@ -1,5 +1,5 @@ /* copy sign, double version. - Copyright (C) 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2002. @@ -38,7 +38,6 @@ mask: #define MO(op) op #endif - .text ENTRY(__copysignf) movss MO(mask),%xmm3 andps %xmm3,%xmm0 diff --git a/sysdeps/x86_64/fpu/s_log1pl.S b/sysdeps/x86_64/fpu/s_log1pl.S index 7fbd0e5aaa..ac2bd22a4f 100644 --- a/sysdeps/x86_64/fpu/s_log1pl.S +++ b/sysdeps/x86_64/fpu/s_log1pl.S @@ -45,7 +45,7 @@ ENTRY(__log1pl) fxam fnstsw fld %st - andb $1,%ah + testb $1, %ah jnz 3f // in case x is NaN or ħInf 4: fabs @@ -62,7 +62,8 @@ ENTRY(__log1pl) 2: fyl2xp1 ret -3: jp 4b // in case x is ħInf +3: testb $4, %ah + jnz 4b // in case x is ħInf fstp %st(1) fstp %st(1) ret diff --git a/sysdeps/x86_64/ldbl2mpn.c b/sysdeps/x86_64/ldbl2mpn.c new file mode 100644 index 0000000000..641b789cd4 --- /dev/null +++ b/sysdeps/x86_64/ldbl2mpn.c @@ -0,0 +1 @@ +#include "../i386/ldbl2mpn.c" diff --git a/sysdeps/x86_64/soft-fp/sfp-machine.h b/sysdeps/x86_64/soft-fp/sfp-machine.h new file mode 100644 index 0000000000..77df02380c --- /dev/null +++ b/sysdeps/x86_64/soft-fp/sfp-machine.h @@ -0,0 +1,51 @@ +#define _FP_W_TYPE_SIZE 64 +#define _FP_W_TYPE unsigned long +#define _FP_WS_TYPE signed long +#define _FP_I_TYPE long + +#define __FP_CLZ(r, x) \ + do { \ + __asm__("bsrq %1,%0" : "=r"(r) : "g"(x) : "cc"); \ + r ^= 63; \ + } while (0) + +#define _FP_NANFRAC_S _FP_QNANBIT_S +#define _FP_NANFRAC_D _FP_QNANBIT_D, 0 +#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 +#define _FP_NANSIGN_S 1 +#define _FP_NANSIGN_D 1 +#define _FP_NANSIGN_Q 1 + +#define _FP_KEEPNANFRACP 1 +/* Here is something Intel misdesigned: the specs don't define + the case where we have two NaNs with same mantissas, but + different sign. Different operations pick up different NaNs. + */ +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if (_FP_FRAC_GT_##wc(X, Y) \ + || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + else \ + { \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R,Y); \ + } \ + R##_c = FP_CLS_NAN; \ + } while (0) + +#define FP_EX_INVALID (1 << 0) +#define FP_EX_DENORM (1 << 1) +#define FP_EX_DIVZERO (1 << 2) +#define FP_EX_OVERFLOW (1 << 3) +#define FP_EX_UNDERFLOW (1 << 4) +#define FP_EX_INEXACT (1 << 5) + +#define FP_RND_NEAREST 0 +#define FP_RND_ZERO 3 +#define FP_RND_PINF 2 +#define FP_RND_MINF 1 + |