diff options
Diffstat (limited to 'sysdeps')
91 files changed, 1371 insertions, 1287 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 88c357ea07..29f500b2d0 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-2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1996-2005, 2006 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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) -#define elf_machine_type_class(type) \ +#if !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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 */ +#endif else _dl_reloc_bad_type (map, r_type, 0); } diff --git a/sysdeps/alpha/libc-tls.c b/sysdeps/alpha/libc-tls.c index 24629e9aca..7e02769171 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 Free Software Foundation, Inc. + Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,8 +20,6 @@ #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 @@ -33,5 +31,3 @@ __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 eee6141c6a..dda91bb806 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-2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -38,6 +38,7 @@ #include <bits/libc-lock.h> #include <hp-timing.h> #include <tls.h> +#include <rtld-lowlevel.h> __BEGIN_DECLS @@ -438,23 +439,18 @@ 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; - /* 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; + /* Flag signalling whether there are gaps in the module ID allocation. */ + EXTERN bool _dl_tls_dtv_gaps; /* Information about the dtv slots. */ EXTERN struct dtv_slotinfo_list { @@ -478,10 +474,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; @@ -489,31 +485,18 @@ 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_VISIBILITY_ATTRIBUTE -# ifdef HAVE_SDATA_SECTION -# define __rtld_local_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"))) -# else -# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) -# endif +# undef __rtld_global_attribute__ +# define __rtld_global_attribute__ __attribute__ ((section (".sdata"))) # else -# define __rtld_local_attribute__ +# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) # endif extern struct rtld_global _rtld_local __rtld_local_attribute__; # undef __rtld_local_attribute__ @@ -549,15 +532,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; @@ -586,6 +569,9 @@ 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; @@ -669,17 +655,10 @@ 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 -# ifdef HAVE_VISIBILITY_ATTRIBUTE -# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) -# else -# define __rtld_local_attribute__ -# endif +# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) extern struct rtld_global_ro _rtld_local_ro attribute_relro __rtld_local_attribute__; extern struct rtld_global_ro _rtld_global_ro @@ -1044,9 +1023,7 @@ 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; @@ -1069,11 +1046,6 @@ 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; @@ -1085,8 +1057,6 @@ 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 6a23ec05e1..06e41ad121 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 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -17,11 +17,6 @@ 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 ab67a18f64..307c4d7020 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 Free Software Foundation, Inc. +# Copyright (C) 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 @@ -92,16 +92,18 @@ 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 "strong_alias (_sys_errlist_internal, __sys_errlist_%s)\n", old; - printf "declare_symbol (__sys_errlist_%s, object, __WORDSIZE/8*%d)\n", \ - old, n; + printf "declare_symbol_alias (__sys_errlist_%s, _sys_errlist_internal,", \ + old; + printf " object, __WORDSIZE/8*%d)\n", 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 "strong_alias (__sys_errlist_%s, ___sys_errlist_%s)\n", old, old; + printf "declare_symbol_alias (___sys_errlist_%s, _sys_errlist_internal,", \ + old; + printf " object, __WORDSIZE/8*%d)\n", n; 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 87099ec14a..2c04ec9b7f 100644 --- a/sysdeps/gnu/netinet/tcp.h +++ b/sysdeps/gnu/netinet/tcp.h @@ -49,6 +49,7 @@ #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 cb1875f9eb..3005f867f0 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 Free Software Foundation, Inc. + Copyright (C) 1997-2000, 2002, 2003, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -40,27 +40,30 @@ 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) -strong_alias (_sys_siglist_internal, __old_sys_siglist) -declare_symbol (__old_sys_siglist, 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) +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 (__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 -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) + +declare_symbol_alias (__old2_sys_sigabbrev, __new_sys_sigabbrev, 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) +declare_symbol_alias (_old2_sys_siglist, __new_sys_siglist, 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 7f2ddc2dc5..bed27559c5 100644 --- a/sysdeps/i386/bits/byteswap.h +++ b/sysdeps/i386/bits/byteswap.h @@ -1,6 +1,5 @@ /* Macros to swap the order of bytes in integer values. - Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 2007 - Free Software Foundation, Inc. + Copyright (C) 1997,1998,2000,2002,2003,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -67,8 +66,7 @@ __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 __nocona__ && !defined __core2__ \ - && !defined __geode__ && !defined __amdfam10__ + && !defined __k6__ # 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 df3edf5460..04296d2a9a 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-2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,9 +34,7 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr) } -#if defined PI_STATIC_AND_HIDDEN \ - && defined HAVE_VISIBILITY_ATTRIBUTE && defined HAVE_HIDDEN \ - && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE +#ifdef PI_STATIC_AND_HIDDEN /* Return the link-time address of _DYNAMIC. Conveniently, this is the first element of the GOT, a special entry that is never relocated. */ @@ -244,7 +242,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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 \ @@ -352,7 +350,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, *reloc_addr = value; break; -#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !defined RTLD_BOOTSTRAP || USE___THREAD case R_386_TLS_DTPMOD32: # ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always the module @@ -476,7 +474,6 @@ 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. */ @@ -513,7 +510,6 @@ 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 ce55b72292..5604e638f5 100644 --- a/sysdeps/i386/fpu/e_log.S +++ b/sysdeps/i386/fpu/e_log.S @@ -36,15 +36,11 @@ 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) - sahf - jc 3f // in case x is NaN or +-Inf -4: fsubl MO(one) // x-1 : x : log(2) + 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) @@ -58,9 +54,4 @@ 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 cd4538b594..128bb2754c 100644 --- a/sysdeps/i386/fpu/e_logf.S +++ b/sysdeps/i386/fpu/e_logf.S @@ -37,15 +37,11 @@ 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) - sahf - jc 3f // in case x is NaN or +-Inf -4: fsubl MO(one) // x-1 : x : log(2) + 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) @@ -59,9 +55,4 @@ 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 551dcf1e46..5023d3012f 100644 --- a/sysdeps/i386/fpu/e_logl.S +++ b/sysdeps/i386/fpu/e_logl.S @@ -37,15 +37,11 @@ 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) - sahf - jc 3f // in case x is NaN or +-Inf -4: fsubl MO(one) // x-1 : x : log(2) + 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) @@ -59,9 +55,4 @@ 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 792f926902..c554ca4ecb 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, 2007 + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -161,11 +161,10 @@ ENTRY(__ieee754_pow) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 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 + 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 fnstsw fxch // x : 1.0 : y sahf @@ -198,10 +197,9 @@ ENTRY(__ieee754_pow) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldl MO(one) // 1 - fldl 4(%esp) // x : 1 - fabs // abs(x) : 1 - fucompp // < 1, == 1, or > 1 + fldl 4(%esp) // x + fabs + fcompl MO(one) // < 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 c91545418d..c835b978b9 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, 2007 + Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -155,11 +155,10 @@ ENTRY(__ieee754_powf) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 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 + 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 fnstsw fxch // x : 1.0 : y sahf @@ -192,10 +191,9 @@ ENTRY(__ieee754_powf) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldl MO(one) // 1 - flds 4(%esp) // x : 1 - fabs // abs(x) : 1 - fucompp // < 1, == 1, or > 1 + flds 4(%esp) // x + fabs + fcompl MO(one) // < 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 6215496207..74f422816a 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, 2007 + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -161,11 +161,10 @@ ENTRY(__ieee754_powl) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 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 + 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 fnstsw fxch // x : 1.0 : y sahf @@ -211,10 +210,9 @@ ENTRY(__ieee754_powl) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldl MO(one) // 1 - fldt 4(%esp) // x : 1 - fabs // abs(x) : 1 - fucompp // < 1, == 1, or > 1 + fldt 4(%esp) // x + fabs + fcompl MO(one) // < 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 deleted file mode 100644 index a426788ef1..0000000000 --- a/sysdeps/i386/fpu/math_private.h +++ /dev/null @@ -1,18 +0,0 @@ -#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 aef0a144e5..5b617cb4e7 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,12 +52,9 @@ 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 */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ } if(esx>=0) { /* x > 0 */ if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { @@ -112,9 +109,12 @@ static char rcsid[] = "$NetBSD: $"; } esy = esx&0x7fff; if(esy==0x7fff) return x+x; /* overflow */ - if(esy==0) { - long double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(esy==0) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_LDOUBLE_WORDS(y,esx,hx,lx); + return y; + } } 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 9bd86a3724..2bd768e448 100644 --- a/sysdeps/i386/fpu/s_nexttoward.c +++ b/sysdeps/i386/fpu/s_nexttoward.c @@ -27,8 +27,7 @@ static char rcsid[] = "$NetBSD: $"; */ #include "math.h" -#include <math_private.h> -#include <float.h> +#include "math_private.h" #ifdef __STDC__ double __nexttoward(double x, long double y) @@ -53,12 +52,10 @@ 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 u; + double x2; INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 @@ -88,14 +85,16 @@ static char rcsid[] = "$NetBSD: $"; hy = hx&0x7ff00000; if(hy>=0x7ff00000) { x = x+x; /* overflow */ - if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to double. */ - asm ("" : "+m"(x)); + /* Force conversion to double. */ + asm ("" : "=m"(x) : "m"(x)); return x; } - if(hy<0x00100000) { - double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy<0x00100000) { /* underflow */ + double x2 = x*x; + if(x2!=x) { /* raise underflow flag */ + INSERT_WORDS(x2,hx,lx); + return x2; + } } INSERT_WORDS(x,hx,lx); return x; diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c index 25f70e4f4d..3fbe53c338 100644 --- a/sysdeps/i386/fpu/s_nexttowardf.c +++ b/sysdeps/i386/fpu/s_nexttowardf.c @@ -19,8 +19,7 @@ static char rcsid[] = "$NetBSD: $"; #endif #include "math.h" -#include <math_private.h> -#include <float.h> +#include "math_private.h" #ifdef __STDC__ float __nexttowardf(float x, long double y) @@ -45,12 +44,10 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float u; + float x2; SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 @@ -72,14 +69,16 @@ static char rcsid[] = "$NetBSD: $"; hy = hx&0x7f800000; if(hy>=0x7f800000) { x = x+x; /* overflow */ - if (FLT_EVAL_METHOD != 0) - /* Force conversion to float. */ - asm ("" : "+m"(x)); + /* Force conversion to float. */ + asm ("" : "=m"(x) : "m"(x)); return x; } - if(hy<0x00800000) { - float u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy<0x00800000) { /* underflow */ + float x2 = x*x; + if(x2!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(x2,hx); + return x2; + } } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h index c748761758..a27734c37e 100644 --- a/sysdeps/i386/i486/bits/atomic.h +++ b/sysdeps/i386/i486/bits/atomic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include <stdint.h> +#include <tls.h> /* For tcbhead_t. */ typedef int8_t atomic8_t; @@ -76,6 +77,40 @@ 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 @@ -85,6 +120,8 @@ 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) \ @@ -100,6 +137,24 @@ 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; \ @@ -112,6 +167,22 @@ 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 @@ -139,21 +210,24 @@ typedef uintmax_t uatomic_max_t; result; }) -#define atomic_exchange_and_add(mem, value) \ +#define __arch_exchange_and_add_body(lock, pfx, mem, value) \ ({ __typeof (*mem) __result; \ __typeof (value) __addval = (value); \ if (sizeof (*mem) == 1) \ - __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \ + __asm __volatile (lock "xaddb %b0, %1" \ : "=r" (__result), "=m" (*mem) \ - : "0" (__addval), "m" (*mem)); \ + : "0" (__addval), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ else if (sizeof (*mem) == 2) \ - __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \ + __asm __volatile (lock "xaddw %w0, %1" \ : "=r" (__result), "=m" (*mem) \ - : "0" (__addval), "m" (*mem)); \ + : "0" (__addval), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ else if (sizeof (*mem) == 4) \ - __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \ + __asm __volatile (lock "xaddl %0, %1" \ : "=r" (__result), "=m" (*mem) \ - : "0" (__addval), "m" (*mem)); \ + : "0" (__addval), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ else \ { \ __typeof (mem) __memp = (mem); \ @@ -161,41 +235,64 @@ typedef uintmax_t uatomic_max_t; __result = *__memp; \ do \ __tmpval = __result; \ - while ((__result = __arch_compare_and_exchange_val_64_acq \ + while ((__result = pfx##_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) \ - (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); \ - } \ - }) + __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) #define atomic_add_negative(mem, value) \ @@ -236,30 +333,42 @@ typedef uintmax_t uatomic_max_t; __result; }) -#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 __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_and_test(mem) \ @@ -281,30 +390,42 @@ typedef uintmax_t uatomic_max_t; __result; }) -#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 __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_and_test(mem) \ @@ -327,21 +448,22 @@ typedef uintmax_t uatomic_max_t; #define atomic_bit_set(mem, bit) \ - (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 (); \ - }) + 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) #define atomic_bit_test_set(mem, bit) \ @@ -364,3 +486,51 @@ 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 4bd5394bec..4fa6adea98 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 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -44,13 +44,9 @@ 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: @@ -384,38 +380,38 @@ END (BP_SYM (memcmp)) .section .rodata ALIGN (2) 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 + .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) #undef bcmp diff --git a/sysdeps/i386/ldbl2mpn.c b/sysdeps/i386/ldbl2mpn.c index 01be777270..bf4e4ff43f 100644 --- a/sysdeps/i386/ldbl2mpn.c +++ b/sysdeps/i386/ldbl2mpn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1996, 1997, 2000, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 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 @@ -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] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; #define N 1 #else #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" @@ -109,13 +109,6 @@ __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 deleted file mode 100644 index ed71ae418a..0000000000 --- a/sysdeps/i386/soft-fp/sfp-machine.h +++ /dev/null @@ -1,89 +0,0 @@ -#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 2739cb00b3..e03a8e926d 100644 --- a/sysdeps/i386/sysdep.h +++ b/sysdeps/i386/sysdep.h @@ -1,5 +1,6 @@ /* Assembler macros for i386. - Copyright (C) 1991-93,95,96,98,2002,2003,2005 Free Software Foundation, Inc. + Copyright (C) 1991-93,95,96,98,2002,2003,2005,2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -132,15 +133,7 @@ lose: SYSCALL_PIC_SETUP \ cfi_adjust_cfa_offset (-4); \ addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx; -# 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) \ +# 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; \ @@ -153,7 +146,6 @@ __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 55349690e3..61b4ea99a7 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 Free Software Foundation, Inc. + Copyright (C) 1995-1997, 2000-2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 USE_TLS && (!defined RTLD_BOOTSTRAP || defined USE___THREAD) +#if !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 13801c848b..351bcc2f10 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, 2007 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2005 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 1; + return 0; /* 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 0; + return 1; } libm_hidden_def (fesetround) diff --git a/sysdeps/ia64/ldbl2mpn.c b/sysdeps/ia64/ldbl2mpn.c deleted file mode 100644 index 641b789cd4..0000000000 --- a/sysdeps/ia64/ldbl2mpn.c +++ /dev/null @@ -1 +0,0 @@ -#include "../i386/ldbl2mpn.c" diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c index 2c0eeae86f..9751284008 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 Free Software Foundation, Inc. + Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -19,8 +19,6 @@ #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 @@ -32,5 +30,3 @@ __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 1e159f2c0b..d9bd8b479f 100644 --- a/sysdeps/ieee754/dbl-64/e_pow.c +++ b/sysdeps/ieee754/dbl-64/e_pow.c @@ -106,28 +106,20 @@ 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 (qy == 0x7ff00000) { + if ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) { 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 (qx == 0x7ff00000) + else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0) return y < 0 ? 0.0 : INF.x; return NaNQ.x; /* y not integer and x<0 */ } - else if (qx == 0x7ff00000) + else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0) { if (k < 0) return y < 0 ? nZERO.x : nINF.x; @@ -137,6 +129,14 @@ 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 600c14621f..e1568e24c9 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,12 +40,9 @@ 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 */ - u = math_opt_barrier (x); - u = u*u; - math_force_eval (u); /* raise underflow flag */ - return x; + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hx>hy) { /* x > y, x -= ulp */ @@ -64,12 +61,15 @@ 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)); + asm ("" : "=m"(x) : "m"(x)); return x; /* overflow */ } - if(hy<0x00800000) { - float u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy<0x00800000) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(y,hx); + return y; + } } 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 7bc869a518..d3df668178 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,12 +47,9 @@ 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 */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ @@ -73,9 +70,12 @@ static char rcsid[] = "$NetBSD: $"; } hy = hx&0x7fff000000000000LL; if(hy==0x7fff000000000000LL) return x+x;/* overflow */ - if(hy==0) { - long double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy==0) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_LDOUBLE_WORDS64(y,hx,lx); + return y; + } } 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 178505c58f..553e401973 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,12 +53,10 @@ 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 u; + double x2; INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if (hy<0||(ix>>20)>(iy>>48)-0x3c00 @@ -89,13 +87,16 @@ static char rcsid[] = "$NetBSD: $"; if(hy>=0x7ff00000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to double. */ - asm ("" : "+m"(x)); + /* Force conversion to float. */ + asm ("" : "=m"(x) : "m"(x)); return x; } - if(hy<0x00100000) { - double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy<0x00100000) { /* underflow */ + double x2 = x*x; + if(x2!=x) { /* raise underflow flag */ + INSERT_WORDS(x2,hx,lx); + return x2; + } } INSERT_WORDS(x,hx,lx); return x; diff --git a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c index 21d1e62dab..8a2d45e2d8 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, 2007 +/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -31,20 +31,19 @@ long double __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) { union ibm_extended_long_double u; - unsigned long lzcount; + unsigned long hidden2, 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 = 0; - exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; + u.ieee.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; @@ -52,6 +51,7 @@ __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,62 +59,14 @@ __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' and either the explicit mantissa is non-zero - or hi is odd, then round up hi and adjust lo (2nd mantissa) + If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) plus change the sign of the low double to compensate. */ - if ((lo & (1LL << 52)) != 0 - && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)))) + if (hidden2) { 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; } @@ -133,18 +85,17 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) if (lzcount > 0) { lo = lo << lzcount; - exponent2 = exponent2 - lzcount; + u.ieee.exponent2 = u.ieee.exponent2 - lzcount; } - if (exponent2 > 0) - u.ieee.exponent2 = exponent2; - else - lo >>= 1 - exponent2; } else - u.ieee.negative2 = 0; + { + u.ieee.negative2 = 0; + u.ieee.exponent2 = 0; + } u.ieee.mantissa3 = lo & 0xffffffffLL; - u.ieee.mantissa2 = (lo >> 32) & 0xfffff; + u.ieee.mantissa2 = (lo >> 32) & 0xffffff; 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 b2ad25e31f..2a7b70fabf 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,2007 + Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -35,24 +35,21 @@ do { \ \ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ - 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)) \ + /* 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 = (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 6999abc250..3ca178a3c5 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,2007 Free Software Foundation, Inc. + Copyright (C) 1997,1999,2002,2004,2006 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,16 +30,14 @@ * -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 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 + * +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 */ int @@ -61,23 +59,12 @@ ___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 { - 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; - } + /* +/- 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 39d0e6a5e3..e35ce50829 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; + int64_t hx,hy,ihx,ihy,ilx,ily; u_int64_t lx,ly; GET_LDOUBLE_WORDS64(hx,lx,x); @@ -43,6 +43,7 @@ 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 */ @@ -52,67 +53,55 @@ static char rcsid[] = "$NetBSD: $"; if(x==y) return y; /* x=y, return y */ if(ihx == 0 && ilx == 0) { /* x == 0 */ - 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; + 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; - 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; - } - 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; + 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++; } - 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; + } 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 && 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; + } + 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; } + 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 e2f6521f57..3335100592 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,12 +55,10 @@ 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 u; + double x2; INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if (hy<0||(ix>>20)>(iy>>52) @@ -91,13 +89,16 @@ static char rcsid[] = "$NetBSD: $"; if(hy>=0x7ff00000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to double. */ - asm ("" : "+m"(x)); + /* Force conversion to float. */ + asm ("" : "=m"(x) : "m"(x)); return x; } - if(hy<0x00100000) { - double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy<0x00100000) { /* underflow */ + double x2 = x*x; + if(x2!=x) { /* raise underflow flag */ + INSERT_WORDS(x2,hx,lx); + return x2; + } } 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 cf655fad16..a9373ff822 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c @@ -19,9 +19,8 @@ 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) @@ -47,12 +46,10 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float u; + float x2; SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hy<0||(ix>>23)>(iy>>52)-0x380 @@ -72,16 +69,13 @@ static char rcsid[] = "$NetBSD: $"; } } hy = hx&0x7f800000; - if(hy>=0x7f800000) { - x = x+x; /* overflow */ - if (FLT_EVAL_METHOD != 0) - /* Force conversion to float. */ - asm ("" : "+m"(x)); - return x; - } + if(hy>=0x7f800000) return x+x; /* overflow */ if(hy<0x00800000) { /* underflow */ - float u = x*x; - math_force_eval (u); /* raise underflow flag */ + float x2 = x*x; + if(x2!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(x2,hx); + return x2; + } } 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 ed0877d6dd..1798261b28 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,12 +48,9 @@ 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 */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ } if(esx<0x8000) { /* x > 0 */ if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) { @@ -88,10 +85,13 @@ static char rcsid[] = "$NetBSD: $"; } } esy = esx&0x7fff; - if(esy==0x7fff) return x+x; /* overflow */ - if(esy==0) { - long double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + 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; + } } 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 e30438482c..7945cb5cb1 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,12 +50,10 @@ 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 u; + double x2; INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 @@ -86,13 +84,16 @@ static char rcsid[] = "$NetBSD: $"; if(hy>=0x7ff00000) { x = x+x; /* overflow */ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1) - /* Force conversion to double. */ - asm ("" : "+m"(x)); + /* Force conversion to float. */ + asm ("" : "=m"(x) : "m"(x)); return x; } - if(hy<0x00100000) { - double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ + if(hy<0x00100000) { /* underflow */ + double x2 = x*x; + if(x2!=x) { /* raise underflow flag */ + INSERT_WORDS(x2,hx,lx); + return x2; + } } 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 6357975ffc..a1c38b5d4c 100644 --- a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c +++ b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c @@ -18,8 +18,7 @@ static char rcsid[] = "$NetBSD: $"; #endif #include "math.h" -#include <math_private.h> -#include <float.h> +#include "math_private.h" #ifdef __STDC__ float __nexttowardf(float x, long double y) @@ -42,12 +41,10 @@ static char rcsid[] = "$NetBSD: $"; return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ - float u; + float x2; SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 @@ -67,16 +64,13 @@ static char rcsid[] = "$NetBSD: $"; } } hy = hx&0x7f800000; - 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 */ + 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; + } } 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 68027f26fa..d52526f719 100644 --- a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c +++ b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c @@ -20,10 +20,7 @@ * Special cases: */ -#include <math.h> -#include <math_private.h> #include <math_ldbl_opt.h> -#include <float.h> float __nldbl_nexttowardf(float x, double y); @@ -42,12 +39,10 @@ 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 u; + float x2; SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; + x2 = x*x; + if(x2==x) return x2; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hy<0||(ix>>23)>(iy>>20)-0x380 @@ -65,16 +60,13 @@ float __nldbl_nexttowardf(float x, double y) hx += 1; } hy = hx&0x7f800000; - 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 */ + 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; + } } SET_FLOAT_WORD(x,hx); return x; diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index fa7da60204..3288f186e5 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 +/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -532,11 +532,9 @@ __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 ca687b8bdf..4628eee2c3 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 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -28,20 +28,24 @@ int __futimes (int fd, const struct timeval tvp[2]) { - struct timeval timevals[2]; + union tv + { + struct timeval tv; + time_value_t tvt; + }; + const union tv *u = (const union tv *) tvp; + union tv nulltv[2]; error_t err; if (tvp == NULL) { /* Setting the number of microseconds to `-1' tells the underlying filesystems to use the current time. */ - timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1; - tvp = timevals; + nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; + u = nulltv; } - err = HURD_DPORT_USE (fd, __file_utimes (port, - *(time_value_t *) &tvp[0], - *(time_value_t *) &tvp[1])); + err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt)); 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 223a47d2f2..972cac57a1 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 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,9 +25,6 @@ /* 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 cf89d8862f..bf5610c467 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 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -28,7 +28,13 @@ int __lutimes (const char *file, const struct timeval tvp[2]) { - struct timeval timevals[2]; + union tv + { + struct timeval tv; + time_value_t tvt; + }; + const union tv *u = (const union tv *) tvp; + union tv nulltv[2]; error_t err; file_t port; @@ -36,15 +42,14 @@ __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. */ - timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1; - tvp = timevals; + nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; + u = nulltv; } port = __file_name_lookup (file, O_NOLINK, 0); if (port == MACH_PORT_NULL) return -1; - err = __file_utimes (port, - *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]); + err = __file_utimes (port, u[0].tvt, u[1].tvt); __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 74f3a342f4..fdc1427feb 100644 --- a/sysdeps/mach/hurd/utimes.c +++ b/sysdeps/mach/hurd/utimes.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-1995, 97, 99, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1991-1995,1997,1999,2000,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 @@ -28,7 +29,13 @@ __utimes (file, tvp) const char *file; const struct timeval tvp[2]; { - struct timeval timevals[2]; + union tv + { + struct timeval tv; + time_value_t tvt; + }; + const union tv *u = (const union tv *) tvp; + union tv nulltv[2]; error_t err; file_t port; @@ -36,19 +43,17 @@ __utimes (file, tvp) { /* Setting the number of microseconds to `-1' tells the underlying filesystems to use the current time. */ - timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1; - tvp = timevals; + nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1; + u = nulltv; } port = __file_name_lookup (file, 0, 0); if (port == MACH_PORT_NULL) return -1; - err = __file_utimes (port, - *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]); + err = __file_utimes (port, u[0].tvt, u[1].tvt); __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 333870cdde..76a09d455d 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,2007 Free Software Foundation, Inc. + Copyright (C) 1990,1991,1995-2001,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 @@ -128,6 +128,10 @@ 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) { @@ -158,10 +162,6 @@ 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 a7e1459c9c..b4966852a7 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] & 0xf0) == 16) + else if (addr[0] == 10 || (addr[0] == 172 && addr[1] == 16) || (addr[0] == 192 && addr[1] == 168)) scope = 5; else @@ -1218,10 +1218,6 @@ 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 } @@ -2089,10 +2085,12 @@ getaddrinfo (const char *name, const char *service, if (q->ai_family == PF_INET6 && in6ai != NULL) { - /* See whether the address is the list of deprecated - or temporary addresses. */ + /* See whether the source address is the list of + deprecated or temporary addresses. */ struct in6addrinfo tmp; - memcpy (tmp.addr, q->ai_addr, IN6ADDRSZ); + struct sockaddr_in6 *sin6p + = (struct sockaddr_in6 *) &results[i].source_addr; + memcpy (tmp.addr, &sin6p->sin6_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 aed899e882..04478309d9 100644 --- a/sysdeps/powerpc/fpu/bits/mathinline.h +++ b/sysdeps/powerpc/fpu/bits/mathinline.h @@ -121,62 +121,4 @@ __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 new file mode 100644 index 0000000000..90021c6d3c --- /dev/null +++ b/sysdeps/powerpc/fpu/math_private.h @@ -0,0 +1,83 @@ +/* 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 4120a02382..fc460993b1 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 Free Software Foundation, Inc. + Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -564,13 +564,12 @@ __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. */ \ @@ -609,7 +608,6 @@ __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 496fa71ecc..a50ffdd1c2 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 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if (!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 /* USE_TLS etc. */ +#endif 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 8fc624ebd9..88cfe71e0b 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 HAVE_BROKEN_ALIAS_ATTRIBUTE && !defined NO_HIDDEN + && !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 cec271bb3a..89a69e1a23 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -1,7 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. PowerPC64 version. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright 1995-2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -260,7 +259,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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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) \ @@ -495,7 +494,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, *reloc_addr = l_addr + reloc->r_addend; } -#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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, @@ -562,7 +561,7 @@ elf_machine_rela (struct link_map *map, #endif return; -#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !defined RTLD_BOOTSTRAP || USE___THREAD case R_PPC64_DTPMOD64: # ifdef RTLD_BOOTSTRAP /* During startup the dynamic linker is always index 1. */ @@ -645,7 +644,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 /* USE_TLS etc. */ +#endif #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 f177f436e9..766d565a9c 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 Free Software Foundation, Inc. + Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,11 +20,9 @@ #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. */ @@ -33,5 +31,3 @@ __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 8bbf858fbf..64bf3423b6 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 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Carl Pederson & Martin Schwidefsky. This file is part of the GNU C Library. @@ -209,17 +209,11 @@ _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. */ -#ifdef USE_TLS -# define elf_machine_type_class(type) \ +#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 @@ -315,7 +309,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = value + reloc->r_addend; break; -#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if (!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 5026a2edad..fa893befdf 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, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001-2005, 2006 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -192,17 +192,11 @@ _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. */ -#ifdef USE_TLS -# define elf_machine_type_class(type) \ +#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 @@ -294,7 +288,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, *reloc_addr = value + reloc->r_addend; break; -#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if (!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 e73c6d79c3..78f70e3880 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 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 02dabaabb4..19aac6a7fe 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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if (!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 314a784dbc..3eee672912 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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ +#if (!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 7c015b1d62..137b44c2b8 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -126,6 +126,9 @@ 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 cca0871ac0..84717c3d96 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 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000,2001,2002,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 @@ -101,7 +101,9 @@ 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 46161a806a..13ccd7acb4 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, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -71,38 +71,17 @@ 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) - goto out_fail; + return -1; *seen_ipv4 = false; *seen_ipv6 = false; bool done = false; + char buf[4096]; + struct iovec iov = { buf, sizeof (buf) }; struct in6ailist { struct in6addrinfo info; @@ -122,10 +101,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) - goto out_fail; + return -1; if (msg.msg_flags & MSG_TRUNC) - goto out_fail; + return -1; struct nlmsghdr *nlmh; for (nlmh = (struct nlmsghdr *) buf; @@ -207,7 +186,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, { *in6ai = malloc (in6ailistlen * sizeof (**in6ai)); if (*in6ai == NULL) - goto out_fail; + return -1; *in6ailen = in6ailistlen; @@ -219,14 +198,7 @@ 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 54524ec120..f73a4b5195 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -120,6 +120,9 @@ 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 @@ -152,6 +155,7 @@ 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 b7a0a4efd4..f69baf943b 100644 --- a/sysdeps/unix/sysv/linux/i386/getgroups.c +++ b/sysdeps/unix/sysv/linux/i386/getgroups.c @@ -52,8 +52,6 @@ __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) { @@ -69,6 +67,9 @@ __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 299574dac4..b5c1b98573 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-2004,2005 Free Software Foundation, Inc. + Copyright (C) 1991,1995-2000,2002-2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -46,18 +46,10 @@ int __libc_missing_rt_sigs; /* 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 -# ifdef __NR_rt_sigaction +#ifdef __NR_rt_sigaction extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; -# 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 +extern void restore (void) asm ("__restore") attribute_hidden; /* 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 02e6935538..82495de03e 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, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -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; - -#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); + if (__netlink_sendreq (h, type) < 0) + return -1; + + size_t this_buf_size = buf_size; + if (__libc_use_alloca (this_buf_size)) + buf = alloca (this_buf_size); else { - buf = malloc (buf_size); + buf = malloc (this_buf_size); if (buf != NULL) use_malloc = true; else goto out_fail; } - struct iovec iov = { buf, buf_size }; + struct iovec iov = { buf, this_buf_size }; - if (__netlink_sendreq (h, type) < 0) - goto out_fail; + if (h->nlm_list != NULL) + new_nlm_list = &h->end_ptr->next; + else + new_nlm_list = &h->nlm_list; while (! done) { @@ -171,7 +171,48 @@ __netlink_request (struct netlink_handle *h, int type) continue; if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0)) - goto out_fail; + { + 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; + } 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 73317ecafd..28c1cb691f 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 Free Software Foundation, Inc. +/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -156,6 +156,8 @@ __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 deleted file mode 100644 index 880b17ef31..0000000000 --- a/sysdeps/unix/sysv/linux/posix_madvise.c +++ /dev/null @@ -1,38 +0,0 @@ -/* 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 new file mode 100644 index 0000000000..189179394b --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/bits/shm.h @@ -0,0 +1,101 @@ +/* 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 deleted file mode 100644 index 6fdc44ff89..0000000000 --- a/sysdeps/unix/sysv/linux/sh/sys/io.h +++ /dev/null @@ -1,48 +0,0 @@ -/* 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 68f173a04d..d8901f7d53 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 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,6 +22,14 @@ #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 { @@ -105,6 +113,16 @@ 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 e16110480f..5776673733 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -10,7 +10,8 @@ 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 -fdatasync - fdatasync Ci:i fdatasync +epoll_pwait EXTRA epoll_pwait Ci:ipiipi epoll_pwait +fdatasync - fdatasync i: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 @@ -31,6 +32,7 @@ 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 0f20367236..bdad5063df 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),stdlib) +ifeq ($(subdir),csu) 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 8a12b09035..db42f209c9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -89,6 +89,9 @@ 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 @@ -113,6 +116,7 @@ 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 d6f4558cef..ab10123858 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 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,17 +33,14 @@ 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. @@ -95,18 +92,95 @@ 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. */ + 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:" #define RESTORE(name, syscall) RESTORE2 (name, syscall) # define RESTORE2(name, syscall) \ -asm \ - ( \ - ".align 16\n" \ - CFI_STARTPROC "\n" \ - "__" #name ":\n" \ - " movq $" #syscall ", %rax\n" \ - " syscall\n" \ - CFI_ENDPROC "\n" \ +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" \ ); /* 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 b3cfe9aa4c..af3e0e544b 100644 --- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym +++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym @@ -18,6 +18,8 @@ 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) @@ -28,6 +30,7 @@ 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 133a68d192..65d6b02008 100644 --- a/sysdeps/x86_64/bits/atomic.h +++ b/sysdeps/x86_64/bits/atomic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include <stdint.h> +#include <tls.h> /* For tcbhead_t. */ typedef int8_t atomic8_t; @@ -80,8 +81,54 @@ typedef uintmax_t uatomic_max_t; ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1" \ : "=a" (ret), "=m" (*mem) \ - : "r" ((long) (newval)), "m" (*mem), \ - "0" ((long) (oldval))); \ + : "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))); \ ret; }) @@ -107,49 +154,76 @@ typedef uintmax_t uatomic_max_t; result; }) -#define atomic_exchange_and_add(mem, value) \ +#define __arch_exchange_and_add_body(lock, mem, value) \ ({ __typeof (*mem) result; \ if (sizeof (*mem) == 1) \ - __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \ + __asm __volatile (lock "xaddb %b0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" (value), "m" (*mem)); \ + : "0" (value), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ else if (sizeof (*mem) == 2) \ - __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \ + __asm __volatile (lock "xaddw %w0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" (value), "m" (*mem)); \ + : "0" (value), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ else if (sizeof (*mem) == 4) \ - __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \ + __asm __volatile (lock "xaddl %0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" (value), "m" (*mem)); \ + : "0" (value), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ else \ - __asm __volatile (LOCK_PREFIX "xaddq %q0, %1" \ + __asm __volatile (lock "xaddq %q0, %1" \ : "=r" (result), "=m" (*mem) \ - : "0" ((long) (value)), "m" (*mem)); \ + : "0" ((long) (value)), "m" (*mem), \ + "i" (offsetof (tcbhead_t, multiple_threads))); \ 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) \ - (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)); \ - }) + __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) #define atomic_add_negative(mem, value) \ @@ -194,24 +268,37 @@ typedef uintmax_t uatomic_max_t; __result; }) -#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 __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_and_test(mem) \ @@ -235,24 +322,37 @@ typedef uintmax_t uatomic_max_t; __result; }) -#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 __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_and_test(mem) \ @@ -277,27 +377,28 @@ typedef uintmax_t uatomic_max_t; #define atomic_bit_set(mem, bit) \ - (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))); \ - }) + 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) #define atomic_bit_test_set(mem, bit) \ @@ -322,3 +423,56 @@ 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 ec2b17889d..e1c861c75f 100644 --- a/sysdeps/x86_64/bits/byteswap.h +++ b/sysdeps/x86_64/bits/byteswap.h @@ -1,6 +1,5 @@ /* Macros to swap the order of bytes in integer values. - Copyright (C) 1997, 1998, 2000, 2002, 2003, 2007 - Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 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 @@ -60,9 +59,7 @@ # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \ || defined __pentiumpro__ || defined __pentium4__ \ || defined __k8__ || defined __athlon__ \ - || defined __k6__ || defined __nocona__ \ - || defined __core2__ || defined __geode__ \ - || defined __amdfam10__) + || defined __k6__) /* 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 73e271775a..31a7013d50 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, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001-2005, 2006 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 USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +#if !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; -#if defined USE_TLS && !defined RESOLVE_CONFLICT_FIND_MAP +#ifndef 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 /* use TLS */ +#endif #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 633234b744..b4343bef45 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) - testb $1, %ah + andb $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,8 +59,7 @@ ENTRY(__ieee754_log10l) fyl2x // log10(x) ret -3: testb $4, %ah - jnz 4b // in case x is ħInf +3: jp 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 f04d30a05a..7a89b94d9f 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 - testb $1, %ah + andb $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,8 +56,7 @@ ENTRY(__ieee754_log2l) fyl2x // log(x) ret -3: testb $4, %ah - jnz 4b // in case x is ħInf +3: jp 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 2ba91eedfd..a0bed663c8 100644 --- a/sysdeps/x86_64/fpu/e_logl.S +++ b/sysdeps/x86_64/fpu/e_logl.S @@ -38,12 +38,8 @@ limit: .double 0.29 ENTRY(__ieee754_logl) fldln2 // log(2) fldt 8(%rsp) // x : log(2) - fxam - fnstsw fld %st // x : x : log(2) - testb $1, %ah - jnz 3f // in case x is NaN or +-Inf -4: fsubl MO(one) // x-1 : x : log(2) + 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) @@ -57,10 +53,4 @@ 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 4959bea7ac..85f4deb3c7 100644 --- a/sysdeps/x86_64/fpu/e_powl.S +++ b/sysdeps/x86_64/fpu/e_powl.S @@ -1,6 +1,5 @@ /* ix87 specific implementation of pow function. - Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007 - Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -147,11 +146,10 @@ ENTRY(__ieee754_powl) 2: /* y is a real number. */ fxch // x : y fldl MO(one) // 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 + 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 fnstsw fxch // x : 1.0 : y test $4500,%eax @@ -192,10 +190,9 @@ ENTRY(__ieee754_powl) // y == ħinf .align ALIGNARG(4) 12: fstp %st(0) // pop y - fldl MO(one) // 1 - fldt 8(%rsp) // x : 1 - fabs // abs(x) : 1 - fucompp // < 1, == 1, or > 1 + fldt 8(%rsp) // x + fabs + fcompl MO(one) // < 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 deleted file mode 100644 index 4febcbb5ec..0000000000 --- a/sysdeps/x86_64/fpu/math_private.h +++ /dev/null @@ -1,21 +0,0 @@ -#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 f1ebcf8bf1..f3d9b0cbb4 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 Free Software Foundation, Inc. + Copyright (C) 2002, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2002. @@ -31,6 +31,8 @@ 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 @@ -42,6 +44,7 @@ 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 f5dc5f78ad..0fbe1d4c96 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 Free Software Foundation, Inc. + Copyright (C) 2002, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2002. @@ -38,6 +38,7 @@ 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 ac2bd22a4f..7fbd0e5aaa 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 - testb $1, %ah + andb $1,%ah jnz 3f // in case x is NaN or ħInf 4: fabs @@ -62,8 +62,7 @@ ENTRY(__log1pl) 2: fyl2xp1 ret -3: testb $4, %ah - jnz 4b // in case x is ħInf +3: jp 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 deleted file mode 100644 index 641b789cd4..0000000000 --- a/sysdeps/x86_64/ldbl2mpn.c +++ /dev/null @@ -1 +0,0 @@ -#include "../i386/ldbl2mpn.c" diff --git a/sysdeps/x86_64/soft-fp/sfp-machine.h b/sysdeps/x86_64/soft-fp/sfp-machine.h deleted file mode 100644 index 77df02380c..0000000000 --- a/sysdeps/x86_64/soft-fp/sfp-machine.h +++ /dev/null @@ -1,51 +0,0 @@ -#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 - |