summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-03-16 20:28:07 +0000
committerUlrich Drepper <drepper@redhat.com>1997-03-16 20:28:07 +0000
commit0d8733c4fc3695c7987548d10c344445f3eb552d (patch)
tree4a2fe41c465963794a6f9d4d1717494972336e14
parent1ed4222e5724ce863a95c15eb530dfab7ef0451c (diff)
downloadglibc-0d8733c4fc3695c7987548d10c344445f3eb552d.tar.gz
glibc-0d8733c4fc3695c7987548d10c344445f3eb552d.tar.xz
glibc-0d8733c4fc3695c7987548d10c344445f3eb552d.zip
1997-03-16 18:43  Ulrich Drepper  <drepper@cygnus.com>

	* manual/filesys.texi: Add documentation for scandir and alphasort.

	* math/math.c (fpclassify): Correct stupid typos.

	* math/libm-test.c: New file.  libm test suite by Andreas Jaeger.

	* nss/nss_files/files-hosts.c: Add gethostbyname2 imlementation.

	* posix/Makefile (routines): Add bsd-getpgrp.
	* posix/bsd-getpgrp.c: New file.
	* posix/unistd.h [__FAVOR_BSD]: Define macro getpgrp which maps
	calls to __bsd_getpgrp.

	* sysdeps/generic/getpgrp.c: De-ANSI-declfy.

	* sysdeps/i386/huge_val.h: New file.  ix87 specific infinity values.
	* sysdeps/m68k/huge_val.h: New file.  m68k specific infinity values.
	* sysdeps/generic/huge_val.h: Remove definition of long double
	definition.  Make it the same as the double definition.

	* sysdeps/libm-i387/e_acos.S: Fix bug in FPU stack handling.
	* sysdeps/libm-i387/e_acosf.S: Likewise.
	* sysdeps/libm-i387/e_acosl.S: Likewise.
	* sysdeps/libm-i387/e_asin.S: Likewise.
	* sysdeps/libm-i387/e_asinf.S: Likewise.
	* sysdeps/libm-i387/e_asinl.S: Likewise.
	* sysdeps/libm-i387/e_exp.S: Likewise.
	* sysdeps/libm-i387/e_expf.S: Likewise.
	* sysdeps/libm-i387/e_expl.S: Likewise.
	* sysdeps/libm-i387/e_scalbn.S: Likewise.
	* sysdeps/libm-i387/e_scalbnf.S: Likewise.
	* sysdeps/libm-i387/e_scalbnl.S: Likewise.

	* sysdeps/libm-i387/e_log.S: Optimize branch code.
	* sysdeps/libm-i387/e_logf.S: Likewise.
	* sysdeps/libm-i387/e_logl.S: Likewise.
	* sysdeps/libm-i387/e_log10.S: Likewise.
	* sysdeps/libm-i387/e_log10f.S: Likewise.
	* sysdeps/libm-i387/e_log10l.S: Likewise.

	* sysdeps/libm-i387/e_pow.S: Major rewrite to handle special cases.
	* sysdeps/libm-i387/e_powf.S: Likewise.
	* sysdeps/libm-i387/e_powl.S: Likewise.

	* sysdeps/libm-i387/e_expm1.S: Change return value for -inf
	argument to -1.0.
	* sysdeps/libm-i387/e_expm1f.S: Likewise.
	* sysdeps/libm-i387/e_expm1l.S: Likewise.

	* sysdeps/libm-i387/e_isinfl.c: Return -1 for -inf.

	* sysdeps/libm-i387/e_logbl.S: Correct return value.  Discard first
	stack element after fxtract.

	* sysdeps/libm-ieee754/e_atan2l.c: New file.  `long double'
	implementation for atan2 function.

	* sysdeps/libm-ieee754/k_standard.c: Return NAN for libm not in
	_SVID_ mode when acos, asin, atan2, log, log10 is called with
	argument out of range.
	Add new error case for pow(+0,neg).

	* sysdeps/libm-ieee754/s_fpclassifyf.c: Correct recognition of
	NaN and +-inf.
	* sysdeps/libm-ieee754/s_fpclassifyl.c: Mask out explicit leading
	digit in stupid 80 bit formats.

	* sysdeps/libm-ieee754/s_isinf.c: Rewrite to return -1 for -inf.
	* sysdeps/libm-ieee754/s_isinff.c: Likewise.
	* sysdeps/libm-ieee754/s_isinfl.c: Likewise.

	* sysdeps/libm-ieee754/s_scalbnl.c (huge, tiny): Adapt values for
	long double type.

	* sysdeps/libm-ieee754/w_atan2.c: Do not raise exception expect when
	in SVID mode.
	* sysdeps/libm-ieee754/w_atan2f.c: Likewise.
	* sysdeps/libm-ieee754/w_atan2l.c: Likewise.

	* sysdeps/libm-ieee754/w_pow.c: Distinguish error cases for x is +0
	or -0.

	* sysdeps/posix/isfdtype.c: Add cast to prevent warning.

	* sysdeps/stub/fcntlbits.h: Update copyright.
	* sysdeps/unix/bsd/fcntlbits.h: Likewise.
	* sysdeps/unix/bsd/bsd4.4/fcntlbits.h: Likewise.
	* sysdeps/unix/bsd/sun/sunos4/fcntlbits.h: Likewise.
	* sysdeps/unix/bsd/ultrix4/fcntlbits.h: Likewise.
	* sysdeps/unix/common/fcntlbits.h: Likewise.
	* sysdeps/unix/sysv/fcntlbits.h: Likewise.  Define O_FSYNC as alias
	of O_SYNC.  Add BSD compatibility macros FAPPEND, FFSYNC, FNONBLOCK,
	and FNDELAY.
	* sysdeps/unix/sysv/irix4/fcntlbits.h: Likewise.

	* sysdeps/unix/readdir_r.c: Don't copy whole `struct dirent' record,
	only reclen bytes.

	* sysdeps/unix/sysv/linux/fcntlbits.h [__USE_GNU]: Add O_READ, O_WRITE
	and O_NORW.
	* sysdeps/unix/sysv/linux/alpha/fcntlbits.h: Likewise.

	* sysdeps/unix/sysv/linux/init-first.h: Add copyright.

	* sysdeps/unix/sysv/linux/fxstat.c: New file.  Rewrite kernel-level
	struct stat to user-level form.
	* sysdeps/unix/sysv/linux/lxstat: New file.
	* sysdeps/unix/sysv/linux/xstat: New file.
	* sysdeps/unix/sysv/linux/kernel_stat.h: Define struct stat used in
	kernel.
	* sysdeps/unix/sysv/linux/statbuf.h (struct stat): Change definition
	to use prescribed types for elements.
	(_STAT_VER): Change to value 3.
	* sysdeps/unix/sysv/linux/alph/statbuf.h: Likewise.
	* sysdeps/unix/sysv/linux/Dist: Add kernel_stat.h.
	* sysdeps/unix/sysv/linux/alpha/Dist: Likewise.

	* time/Makefile: Correct dependencies for test-tz.

1997-03-16 14:59  Philip Blundell  <phil@london.uk.eu.org>

	* resolv/netdb.h: Add prototypes for gai_strerror and getnameinfo
	(needed for IPv6 basic sockets API).

1997-03-16 15:02  a sun  <asun@zoology.washington.edu>

	* sysdeps/unix/sysv/linux/net/if_ppp.h: Don't use incompatible
	kernel header.
	* sysdeps/unix/sysv/linux/net/ppp_defs.h: Likewise.

1997-03-14 17:15  Ulrich Drepper  <drepper@cygnus.com>

	* db/hash/hash_bigkey.c (__big_delete): Don't call __free_ovflpage
	without testing for last_bfp to be NULL.
	Reported by fabsoft@fabserver1.zarm.uni-bremen.de.

1997-03-13 11:42  Jim Meyering  <meyering@asic.sc.ti.com>

	* time/mktime.c (TIME_T_MIN): Work around a bug in Cray C 5.0.3.0.

1997-03-14 04:00  Kurt Garloff  <garloff@kg1.ping.de>

	* sysdeps/unix/sysv/linux/fcntlbits.h (O_FSYNC): Make alias for O_SYNC.
	(FASYNC): Move to __USE_BSD section.  Create new macro O_ASYNC.

1997-03-14 02:50  Ulrich Drepper  <drepper@cygnus.com>

	* nis/nss_nis/nis-hosts.c (_nss_nis_gethostbyname2_r): New
	functions.  Compare result for correct address type.
	(_nss_nis_gethostbyname_r): Use _nss_nis_gethostbyname2_r.
	Reported by Mirko Streckenbach <mirko@marian.hil.de>.

1997-02-17 01:40  Zlatko Calusic  <zcalusic@srce.hr>

	* time/strptime.c (recursive): Return rp to caller.
	(strptime_internal): First check for long names, then abbreviated
	(month & weekday).

1997-03-10 19:44  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makeconfig: Remove useless definitions of ASFLAGS-%.
	* config.make.in (ASFLAGS-.so): Remove.
	* configure.in: Don't substitute ASFLAGS_SO.
	* sysdeps/sparc/configure.in: Remove file.
	* sysdeps/sparc/Makefile (ASFLAGS-.so): Define.

1997-03-11 17:00  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* time/strptime.c (strptime_internal) [case 'Y']: Always subtract
	1900 from year, regardless of century.

1997-03-12 05:43  Ulrich Drepper  <drepper@cygnus.com>

	* stdlib/strtod.c (_tens_in_limb) [BITS_PER_MP_LIMB > 32]: Make
	all numbers unsigned to make buggy gccs happy.
	Patch by Bryan W. Headley <bheadley@interaccess.com>.

	* sysdeps/unix/sysv/linux/netinet/ip.h: Add backward-compatibility
	definitions.  Patch by a sun <asun@zoology.washington.edu>.
	Pretty print header.

	* Makerules (build-shlib): Also create symlink if library is versioned.
	based on a patch by H.J. Lu <hjl@gnu.ai.mit.edu>.
	Remove special rule to libc.so symlink.

1997-03-11 20:16  Andreas Jaeger  <aj@arthur.pfalz.de>

	* manual/math.texi (Domain and Range Errors): Change descriptions
	according to recent changes for ISO C 9X.

1997-03-11 22:39  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/libm-ieee754/k_standard.c (__kernel_standard): Correct
	return values for acos, asin, and atan2.
	Reported by Andreas Jaeger <aj@arthur.pfalz.de>.

1997-03-10 18:16 Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

	* ypclnt.c (__yp_bind): Fix possible buffer overflow.

1997-03-10 18:06  Bernd Schmidt  <crux@Pool.Informatik.RWTH-Aachen.DE>

	* dirent/alphasort.c (alphasort): Interpret arguments as pointers
	to pointers to directory entries so that alphasort really can be
	used as argument for scandir.

1997-03-09 23:33  Andreas Jaeger  <aj@arthur.pfalz.de>

	* string/strdup.c: Declare memcpy if !(_LIBC || STDC_HEADERS)
	instead of strcpy.

1997-03-10 03:34  Ulrich Drepper  <drepper@cygnus.com>

	* catgets/catgets.c (catopen): Always add NLSPATH to search path for
	catalogs, not only if the envvar NLSPATH is not available.
	Reported by Andries.Brouwer@cwi.nl.

1997-03-10 02:46  Ulrich Drepper  <drepper@cygnus.com>

	* Makeconfig (localtime-file): Don't define using installation
	directory.
	(inst_localtime-file): New variable.
	* time/Makefile (installed-localtime-file): Use inst_localtime-file.
	Reported by Edward Seidl <seidl@janed.com>.

1997-03-10 02:31  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* time/Makefile: Add source files to dependencies for test data.

1997-03-09 22:53  Thorsten Kukuk  <kukuk@weber.uni-paderborn.de>

	* nis/nss_nis/nis-ethers.c: Don't ignore return value of yp_all.
	* nis/nss_nis/nis-proto.c: Likewise.
	* nis/nss_nis/nis-rpc.c: Likewise.
	* nis/nss_nis/nis-service.c: Likewise.

1997-03-08 14:37  Miguel de Icaza  <miguel@nuclecu.unam.mx>

	* sysdeps/sparc/dl-machine.h (elf_machine_rela): Upgrade to
	versioning;  Added missing R_SPARC_WDISP30 handling.
	(RTLD_START): Implement it.

	* sysdeps/unix/sysv/linux/sparc/brk.c: Fix.

	* sysdeps/unix/sysv/linux/sparc/start.c: Startup code for
	Linux/SPARC.

1997-03-02 18:06  Miguel de Icaza  <miguel@nuclecu.unam.mx>

	* sysdeps/sparc/dl-machine.h (RTLD_START): Make arg as expected by
	the dynamic linker instead of having a new conditional define.
	Thanks to Richard Henderson for pointing this out.
	* elf/rtld.c: Remove usage of ELF_ADJUST_ARG.

1997-03-20 20:44  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/euidaccess.c: Define as __euidaccess and make
	euidaccess weak alias.

1997-03-07 10:30  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>

	* stdio-common/printf_fphex.c (MIN): New macro.

	* sysdeps/generic/netinet/in.h: Include <sys/types.h>.

	* sysdeps/generic/sys/mman.h (msync): Mention third arg.

	* sysdeps/generic/netinet/in.h: Add definitions for IPv6 basic
	API.  (See change by Philip Blundell on Feb 16, 1997.)

1997-03-05 10:40  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>

	* hurd/hurd.h (vpprintf): Include <stdarg.h>.  New declaration.

	* hurd/set-host.c (_hurd_set_host_config): Cast second arg to
	__file_name_split.

	* mach/mach_error.c (mach_error_string_int): Give full prototype.
	* mach/errstring.c (mach_error_string_int): Likewise.
	* mach/error_compat.c (__mach_error_map_compat): Likewise.
	* hurd/vpprintf.c (pwrite, vpprintf): Likewise.
	* stdio/vasprintf.c (vasprintf): Likewise.

	* mach/mach/mach_traps.h: Include <mach/kern_return.h>.

	* mach/spin-solid.c: Include <mach/mach_traps.h>.
	* mach/spin-solid.c (__spin_lock_solid): Provide arg to
	swtch_pri.

	* mach/mach_init.c: Include <mach/mig_support.h>.

	* mach/mach_error.h (mach_error_string, mach_error,
	mach_error_type): Always provide prototypes.

	* mach/mach/error.h (mach_error_fn_t): Comment out declaration; it
	appears to be entirely unused dead code.

	* stdio/stdio.h (freopen): Fix spelling error.

1997-03-02 13:38  Miles Bader  <miles@gnu.ai.mit.edu>

	* string/argz.h (__need_error_t): New macro, before including <errno.h>
	[!__const] (__const): New macro.
	[!__error_t_defined] (error_t): New typedef.

	* sysdeps/generic/socketbits.h: Add PF_FILE as synonym for PF_LOCAL
	* sysdeps/unix/sysv/linux/socketbits.h: Likewise.
-rw-r--r--ChangeLog311
-rw-r--r--FAQ23
-rw-r--r--INSTALL30
-rw-r--r--Makeconfig15
-rw-r--r--Makerules8
-rw-r--r--catgets/catgets.c13
-rw-r--r--config.make.in3
-rwxr-xr-xconfigure3
-rw-r--r--configure.in2
-rw-r--r--db/hash/hash_bigkey.c2
-rw-r--r--dirent/alphasort.c4
-rw-r--r--elf/rtld.c4
-rw-r--r--hurd/hurd.h7
-rw-r--r--hurd/set-host.c2
-rw-r--r--hurd/vpprintf.c14
-rw-r--r--inet/rcmd.c8
-rw-r--r--mach/error_compat.c22
-rw-r--r--mach/errstring.c24
-rw-r--r--mach/mach/error.h14
-rw-r--r--mach/mach/mach_traps.h4
-rw-r--r--mach/mach_error.c21
-rw-r--r--mach/mach_error.h28
-rw-r--r--mach/mach_init.c1
-rw-r--r--mach/spin-solid.c3
-rw-r--r--manual/examples/dir2.c29
-rw-r--r--manual/filesys.texi70
-rw-r--r--manual/math.texi12
-rw-r--r--math/libm-test.c1520
-rw-r--r--math/math.h4
-rw-r--r--nis/nss_nis/nis-ethers.c27
-rw-r--r--nis/nss_nis/nis-hosts.c26
-rw-r--r--nis/nss_nis/nis-proto.c5
-rw-r--r--nis/nss_nis/nis-rpc.c5
-rw-r--r--nis/nss_nis/nis-service.c35
-rw-r--r--nis/ypclnt.c5
-rw-r--r--nss/nss_files/files-hosts.c7
-rw-r--r--posix/Makefile2
-rw-r--r--posix/bsd-getpgrp.c30
-rw-r--r--posix/unistd.h40
-rw-r--r--resolv/netdb.h10
-rw-r--r--stdio-common/printf_fphex.c4
-rw-r--r--stdio/stdio.h10
-rw-r--r--stdio/vasprintf.c7
-rw-r--r--stdlib/strtod.c8
-rw-r--r--string/strdup.c2
-rw-r--r--sysdeps/generic/getpgrp.c31
-rw-r--r--sysdeps/generic/netinet/in.h93
-rw-r--r--sysdeps/generic/sys/mman.h6
-rw-r--r--sysdeps/i386/huge_val.h92
-rw-r--r--sysdeps/ieee754/huge_val.h18
-rw-r--r--sysdeps/libm-i387/e_acos.S14
-rw-r--r--sysdeps/libm-i387/e_acosf.S2
-rw-r--r--sysdeps/libm-i387/e_acosl.S2
-rw-r--r--sysdeps/libm-i387/e_asin.S2
-rw-r--r--sysdeps/libm-i387/e_asinf.S2
-rw-r--r--sysdeps/libm-i387/e_asinl.S2
-rw-r--r--sysdeps/libm-i387/e_exp.S3
-rw-r--r--sysdeps/libm-i387/e_expf.S3
-rw-r--r--sysdeps/libm-i387/e_expl.S3
-rw-r--r--sysdeps/libm-i387/e_log.S4
-rw-r--r--sysdeps/libm-i387/e_log10.S4
-rw-r--r--sysdeps/libm-i387/e_log10f.S4
-rw-r--r--sysdeps/libm-i387/e_log10l.S4
-rw-r--r--sysdeps/libm-i387/e_logf.S4
-rw-r--r--sysdeps/libm-i387/e_logl.S4
-rw-r--r--sysdeps/libm-i387/e_pow.S219
-rw-r--r--sysdeps/libm-i387/e_powf.S230
-rw-r--r--sysdeps/libm-i387/e_powl.S206
-rw-r--r--sysdeps/libm-i387/s_expm1.S9
-rw-r--r--sysdeps/libm-i387/s_expm1f.S9
-rw-r--r--sysdeps/libm-i387/s_expm1l.S9
-rw-r--r--sysdeps/libm-i387/s_isinfl.c12
-rw-r--r--sysdeps/libm-i387/s_logbl.S1
-rw-r--r--sysdeps/libm-i387/s_scalbn.S1
-rw-r--r--sysdeps/libm-i387/s_scalbnf.S1
-rw-r--r--sysdeps/libm-i387/s_scalbnl.S1
-rw-r--r--sysdeps/libm-ieee754/e_atan2l.c136
-rw-r--r--sysdeps/libm-ieee754/s_fpclassifyl.c1
-rw-r--r--sysdeps/libm-ieee754/s_isinf.c13
-rw-r--r--sysdeps/libm-ieee754/s_isinff.c11
-rw-r--r--sysdeps/libm-ieee754/s_isinfl.c10
-rw-r--r--sysdeps/libm-ieee754/s_scalbnl.c8
-rw-r--r--sysdeps/libm-ieee754/w_atan2.c7
-rw-r--r--sysdeps/libm-ieee754/w_atan2f.c10
-rw-r--r--sysdeps/libm-ieee754/w_atan2l.c5
-rw-r--r--sysdeps/libm-ieee754/w_pow.c5
-rw-r--r--sysdeps/libm-ieee754/w_powf.c17
-rw-r--r--sysdeps/libm-ieee754/w_powl.c5
-rw-r--r--sysdeps/m68k/huge_val.h92
-rw-r--r--sysdeps/mach/hurd/euidaccess.c5
-rw-r--r--sysdeps/posix/isfdtype.c33
-rw-r--r--sysdeps/sparc/dl-machine.h85
-rw-r--r--sysdeps/sparc/elf/Makefile4
-rw-r--r--sysdeps/sparc/elf/start.c68
-rw-r--r--sysdeps/stub/fcntlbits.h34
-rw-r--r--sysdeps/unix/bsd/bsd4.4/fcntlbits.h34
-rw-r--r--sysdeps/unix/bsd/fcntlbits.h34
-rw-r--r--sysdeps/unix/bsd/sun/sunos4/fcntlbits.h30
-rw-r--r--sysdeps/unix/bsd/ultrix4/fcntlbits.h34
-rw-r--r--sysdeps/unix/common/fcntlbits.h36
-rw-r--r--sysdeps/unix/readdir_r.c8
-rw-r--r--sysdeps/unix/sysv/fcntlbits.h12
-rw-r--r--sysdeps/unix/sysv/irix4/fcntlbits.h40
-rw-r--r--sysdeps/unix/sysv/linux/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/fcntlbits.h10
-rw-r--r--sysdeps/unix/sysv/linux/alpha/kernel_stat.h19
-rw-r--r--sysdeps/unix/sysv/linux/alpha/statbuf.h36
-rw-r--r--sysdeps/unix/sysv/linux/fcntlbits.h10
-rw-r--r--sysdeps/unix/sysv/linux/fxstat.c92
-rw-r--r--sysdeps/unix/sysv/linux/init-first.h21
-rw-r--r--sysdeps/unix/sysv/linux/kernel_stat.h31
-rw-r--r--sysdeps/unix/sysv/linux/lxstat.c92
-rw-r--r--sysdeps/unix/sysv/linux/net/if_ppp.h158
-rw-r--r--sysdeps/unix/sysv/linux/net/ppp_defs.h3
-rw-r--r--sysdeps/unix/sysv/linux/netinet/ip.h168
-rw-r--r--sysdeps/unix/sysv/linux/sparc/brk.c2
-rw-r--r--sysdeps/unix/sysv/linux/statbuf.h25
-rw-r--r--sysdeps/unix/sysv/linux/xstat.c92
-rw-r--r--time/Makefile25
-rw-r--r--time/mktime.c6
-rw-r--r--time/strptime.c36
122 files changed, 4403 insertions, 621 deletions
diff --git a/ChangeLog b/ChangeLog
index 63679898f4..55f6b18e68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,310 @@
+1997-03-16 18:43  Ulrich Drepper  <drepper@cygnus.com>
+
+	* manual/filesys.texi: Add documentation for scandir and alphasort.
+
+	* math/math.c (fpclassify): Correct stupid typos.
+
+	* math/libm-test.c: New file.  libm test suite by Andreas Jaeger.
+
+	* nss/nss_files/files-hosts.c: Add gethostbyname2 imlementation.
+
+	* posix/Makefile (routines): Add bsd-getpgrp.
+	* posix/bsd-getpgrp.c: New file.
+	* posix/unistd.h [__FAVOR_BSD]: Define macro getpgrp which maps
+	calls to __bsd_getpgrp.
+
+	* sysdeps/generic/getpgrp.c: De-ANSI-declfy.
+
+	* sysdeps/i386/huge_val.h: New file.  ix87 specific infinity values.
+	* sysdeps/m68k/huge_val.h: New file.  m68k specific infinity values.
+	* sysdeps/generic/huge_val.h: Remove definition of long double
+	definition.  Make it the same as the double definition.
+
+	* sysdeps/libm-i387/e_acos.S: Fix bug in FPU stack handling.
+	* sysdeps/libm-i387/e_acosf.S: Likewise.
+	* sysdeps/libm-i387/e_acosl.S: Likewise.
+	* sysdeps/libm-i387/e_asin.S: Likewise.
+	* sysdeps/libm-i387/e_asinf.S: Likewise.
+	* sysdeps/libm-i387/e_asinl.S: Likewise.
+	* sysdeps/libm-i387/e_exp.S: Likewise.
+	* sysdeps/libm-i387/e_expf.S: Likewise.
+	* sysdeps/libm-i387/e_expl.S: Likewise.
+	* sysdeps/libm-i387/e_scalbn.S: Likewise.
+	* sysdeps/libm-i387/e_scalbnf.S: Likewise.
+	* sysdeps/libm-i387/e_scalbnl.S: Likewise.
+
+	* sysdeps/libm-i387/e_log.S: Optimize branch code.
+	* sysdeps/libm-i387/e_logf.S: Likewise.
+	* sysdeps/libm-i387/e_logl.S: Likewise.
+	* sysdeps/libm-i387/e_log10.S: Likewise.
+	* sysdeps/libm-i387/e_log10f.S: Likewise.
+	* sysdeps/libm-i387/e_log10l.S: Likewise.
+
+	* sysdeps/libm-i387/e_pow.S: Major rewrite to handle special cases.
+	* sysdeps/libm-i387/e_powf.S: Likewise.
+	* sysdeps/libm-i387/e_powl.S: Likewise.
+
+	* sysdeps/libm-i387/e_expm1.S: Change return value for -inf
+	argument to -1.0.
+	* sysdeps/libm-i387/e_expm1f.S: Likewise.
+	* sysdeps/libm-i387/e_expm1l.S: Likewise.
+
+	* sysdeps/libm-i387/e_isinfl.c: Return -1 for -inf.
+
+	* sysdeps/libm-i387/e_logbl.S: Correct return value.  Discard first
+	stack element after fxtract.
+
+	* sysdeps/libm-ieee754/e_atan2l.c: New file.  `long double'
+	implementation for atan2 function.
+
+	* sysdeps/libm-ieee754/k_standard.c: Return NAN for libm not in
+	_SVID_ mode when acos, asin, atan2, log, log10 is called with
+	argument out of range.
+	Add new error case for pow(+0,neg).
+
+	* sysdeps/libm-ieee754/s_fpclassifyf.c: Correct recognition of
+	NaN and +-inf.
+	* sysdeps/libm-ieee754/s_fpclassifyl.c: Mask out explicit leading
+	digit in stupid 80 bit formats.
+
+	* sysdeps/libm-ieee754/s_isinf.c: Rewrite to return -1 for -inf.
+	* sysdeps/libm-ieee754/s_isinff.c: Likewise.
+	* sysdeps/libm-ieee754/s_isinfl.c: Likewise.
+
+	* sysdeps/libm-ieee754/s_scalbnl.c (huge, tiny): Adapt values for
+	long double type.
+
+	* sysdeps/libm-ieee754/w_atan2.c: Do not raise exception expect when
+	in SVID mode.
+	* sysdeps/libm-ieee754/w_atan2f.c: Likewise.
+	* sysdeps/libm-ieee754/w_atan2l.c: Likewise.
+
+	* sysdeps/libm-ieee754/w_pow.c: Distinguish error cases for x is +0
+	or -0.
+
+	* sysdeps/posix/isfdtype.c: Add cast to prevent warning.
+
+	* sysdeps/stub/fcntlbits.h: Update copyright.
+	* sysdeps/unix/bsd/fcntlbits.h: Likewise.
+	* sysdeps/unix/bsd/bsd4.4/fcntlbits.h: Likewise.
+	* sysdeps/unix/bsd/sun/sunos4/fcntlbits.h: Likewise.
+	* sysdeps/unix/bsd/ultrix4/fcntlbits.h: Likewise.
+	* sysdeps/unix/common/fcntlbits.h: Likewise.
+	* sysdeps/unix/sysv/fcntlbits.h: Likewise.  Define O_FSYNC as alias
+	of O_SYNC.  Add BSD compatibility macros FAPPEND, FFSYNC, FNONBLOCK,
+	and FNDELAY.
+	* sysdeps/unix/sysv/irix4/fcntlbits.h: Likewise.
+
+	* sysdeps/unix/readdir_r.c: Don't copy whole `struct dirent' record,
+	only reclen bytes.
+
+	* sysdeps/unix/sysv/linux/fcntlbits.h [__USE_GNU]: Add O_READ, O_WRITE
+	and O_NORW.
+	* sysdeps/unix/sysv/linux/alpha/fcntlbits.h: Likewise.
+
+	* sysdeps/unix/sysv/linux/init-first.h: Add copyright.
+
+	* sysdeps/unix/sysv/linux/fxstat.c: New file.  Rewrite kernel-level
+	struct stat to user-level form.
+	* sysdeps/unix/sysv/linux/lxstat: New file.
+	* sysdeps/unix/sysv/linux/xstat: New file.
+	* sysdeps/unix/sysv/linux/kernel_stat.h: Define struct stat used in
+	kernel.
+	* sysdeps/unix/sysv/linux/statbuf.h (struct stat): Change definition
+	to use prescribed types for elements.
+	(_STAT_VER): Change to value 3.
+	* sysdeps/unix/sysv/linux/alph/statbuf.h: Likewise.
+	* sysdeps/unix/sysv/linux/Dist: Add kernel_stat.h.
+	* sysdeps/unix/sysv/linux/alpha/Dist: Likewise.
+
+	* time/Makefile: Correct dependencies for test-tz.
+
+1997-03-16 14:59  Philip Blundell  <phil@london.uk.eu.org>
+
+	* resolv/netdb.h: Add prototypes for gai_strerror and getnameinfo
+	(needed for IPv6 basic sockets API).
+
+1997-03-16 15:02  a sun  <asun@zoology.washington.edu>
+
+	* sysdeps/unix/sysv/linux/net/if_ppp.h: Don't use incompatible
+	kernel header.
+	* sysdeps/unix/sysv/linux/net/ppp_defs.h: Likewise.
+
+1997-03-14 17:15  Ulrich Drepper  <drepper@cygnus.com>
+
+	* db/hash/hash_bigkey.c (__big_delete): Don't call __free_ovflpage
+	without testing for last_bfp to be NULL.
+	Reported by fabsoft@fabserver1.zarm.uni-bremen.de.
+
+1997-03-13 11:42  Jim Meyering  <meyering@asic.sc.ti.com>
+
+	* time/mktime.c (TIME_T_MIN): Work around a bug in Cray C 5.0.3.0.
+
+1997-03-14 04:00  Kurt Garloff  <garloff@kg1.ping.de>
+
+	* sysdeps/unix/sysv/linux/fcntlbits.h (O_FSYNC): Make alias for O_SYNC.
+	(FASYNC): Move to __USE_BSD section.  Create new macro O_ASYNC.
+
+1997-03-14 02:50  Ulrich Drepper  <drepper@cygnus.com>
+
+	* nis/nss_nis/nis-hosts.c (_nss_nis_gethostbyname2_r): New
+	functions.  Compare result for correct address type.
+	(_nss_nis_gethostbyname_r): Use _nss_nis_gethostbyname2_r.
+	Reported by Mirko Streckenbach <mirko@marian.hil.de>.
+
+1997-02-17 01:40  Zlatko Calusic  <zcalusic@srce.hr>
+
+	* time/strptime.c (recursive): Return rp to caller.
+	(strptime_internal): First check for long names, then abbreviated
+	(month & weekday).
+
+1997-03-10 19:44  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* Makeconfig: Remove useless definitions of ASFLAGS-%.
+	* config.make.in (ASFLAGS-.so): Remove.
+	* configure.in: Don't substitute ASFLAGS_SO.
+	* sysdeps/sparc/configure.in: Remove file.
+	* sysdeps/sparc/Makefile (ASFLAGS-.so): Define.
+
+1997-03-11 17:00  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* time/strptime.c (strptime_internal) [case 'Y']: Always subtract
+	1900 from year, regardless of century.
+
+1997-03-12 05:43  Ulrich Drepper  <drepper@cygnus.com>
+
+	* stdlib/strtod.c (_tens_in_limb) [BITS_PER_MP_LIMB > 32]: Make
+	all numbers unsigned to make buggy gccs happy.
+	Patch by Bryan W. Headley <bheadley@interaccess.com>.
+
+	* sysdeps/unix/sysv/linux/netinet/ip.h: Add backward-compatibility
+	definitions.  Patch by a sun <asun@zoology.washington.edu>.
+	Pretty print header.
+
+	* Makerules (build-shlib): Also create symlink if library is versioned.
+	based on a patch by H.J. Lu <hjl@gnu.ai.mit.edu>.
+	Remove special rule to libc.so symlink.
+
+1997-03-11 20:16  Andreas Jaeger  <aj@arthur.pfalz.de>
+
+	* manual/math.texi (Domain and Range Errors): Change descriptions
+	according to recent changes for ISO C 9X.
+
+1997-03-11 22:39  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/libm-ieee754/k_standard.c (__kernel_standard): Correct
+	return values for acos, asin, and atan2.
+	Reported by Andreas Jaeger <aj@arthur.pfalz.de>.
+
+1997-03-10 18:16 Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+	* ypclnt.c (__yp_bind): Fix possible buffer overflow.
+
+1997-03-10 18:06  Bernd Schmidt  <crux@Pool.Informatik.RWTH-Aachen.DE>
+
+	* dirent/alphasort.c (alphasort): Interpret arguments as pointers
+	to pointers to directory entries so that alphasort really can be
+	used as argument for scandir.
+
+1997-03-09 23:33  Andreas Jaeger  <aj@arthur.pfalz.de>
+
+	* string/strdup.c: Declare memcpy if !(_LIBC || STDC_HEADERS)
+	instead of strcpy.
+
+1997-03-10 03:34  Ulrich Drepper  <drepper@cygnus.com>
+
+	* catgets/catgets.c (catopen): Always add NLSPATH to search path for
+	catalogs, not only if the envvar NLSPATH is not available.
+	Reported by Andries.Brouwer@cwi.nl.
+
+1997-03-10 02:46  Ulrich Drepper  <drepper@cygnus.com>
+
+	* Makeconfig (localtime-file): Don't define using installation
+	directory.
+	(inst_localtime-file): New variable.
+	* time/Makefile (installed-localtime-file): Use inst_localtime-file.
+	Reported by Edward Seidl <seidl@janed.com>.
+
+1997-03-10 02:31  H.J. Lu  <hjl@gnu.ai.mit.edu>
+
+	* time/Makefile: Add source files to dependencies for test data.
+
+1997-03-09 22:53  Thorsten Kukuk  <kukuk@weber.uni-paderborn.de>
+
+	* nis/nss_nis/nis-ethers.c: Don't ignore return value of yp_all.
+	* nis/nss_nis/nis-proto.c: Likewise.
+	* nis/nss_nis/nis-rpc.c: Likewise.
+	* nis/nss_nis/nis-service.c: Likewise.
+
+1997-03-08 14:37  Miguel de Icaza  <miguel@nuclecu.unam.mx>
+
+	* sysdeps/sparc/dl-machine.h (elf_machine_rela): Upgrade to
+	versioning;  Added missing R_SPARC_WDISP30 handling.
+	(RTLD_START): Implement it.
+
+	* sysdeps/unix/sysv/linux/sparc/brk.c: Fix.
+
+	* sysdeps/unix/sysv/linux/sparc/start.c: Startup code for
+	Linux/SPARC.
+
+1997-03-02 18:06  Miguel de Icaza  <miguel@nuclecu.unam.mx>
+
+	* sysdeps/sparc/dl-machine.h (RTLD_START): Make arg as expected by
+	the dynamic linker instead of having a new conditional define.
+	Thanks to Richard Henderson for pointing this out.
+	* elf/rtld.c: Remove usage of ELF_ADJUST_ARG.
+
+1997-03-20 20:44  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* sysdeps/mach/hurd/euidaccess.c: Define as __euidaccess and make
+	euidaccess weak alias.
+
+1997-03-07 10:30  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* stdio-common/printf_fphex.c (MIN): New macro.
+
+	* sysdeps/generic/netinet/in.h: Include <sys/types.h>.
+
+	* sysdeps/generic/sys/mman.h (msync): Mention third arg.
+
+	* sysdeps/generic/netinet/in.h: Add definitions for IPv6 basic
+	API.  (See change by Philip Blundell on Feb 16, 1997.)
+
+1997-03-05 10:40  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* hurd/hurd.h (vpprintf): Include <stdarg.h>.  New declaration.
+
+	* hurd/set-host.c (_hurd_set_host_config): Cast second arg to
+	__file_name_split.
+
+	* mach/mach_error.c (mach_error_string_int): Give full prototype.
+	* mach/errstring.c (mach_error_string_int): Likewise.
+	* mach/error_compat.c (__mach_error_map_compat): Likewise.
+	* hurd/vpprintf.c (pwrite, vpprintf): Likewise.
+	* stdio/vasprintf.c (vasprintf): Likewise.
+
+	* mach/mach/mach_traps.h: Include <mach/kern_return.h>.
+
+	* mach/spin-solid.c: Include <mach/mach_traps.h>.
+	* mach/spin-solid.c (__spin_lock_solid): Provide arg to
+	swtch_pri.
+
+	* mach/mach_init.c: Include <mach/mig_support.h>.
+
+	* mach/mach_error.h (mach_error_string, mach_error,
+	mach_error_type): Always provide prototypes.
+
+	* mach/mach/error.h (mach_error_fn_t): Comment out declaration; it
+	appears to be entirely unused dead code.
+
+	* stdio/stdio.h (freopen): Fix spelling error.
+
+1997-03-02 13:38  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* string/argz.h (__need_error_t): New macro, before including <errno.h>
+	[!__const] (__const): New macro.
+	[!__error_t_defined] (error_t): New typedef.
+
 1997-03-09 06:59  Ulrich Drepper  <drepper@cygnus.com>
 
 	* Makeconfig: Add ASFLAGS-% flags for SPARC assembler which need
@@ -26,9 +333,9 @@
 	* sysdeps/wordsize-32/inttypes.h: New file.
 	* sysdeps/wordsize-64/inttypes.h: New file.
 
-	* sysdpes/generic/socketbits.h: Add PF_FILE as synonym for PF_LOCAL
+	* sysdeps/generic/socketbits.h: Add PF_FILE as synonym for PF_LOCAL
 	and AF_FILE as synonym for AF_LOCAL.
-	* sysdpes/unix/sysv/linux/socketbits.h: Likewise.
+	* sysdeps/unix/sysv/linux/socketbits.h: Likewise.
 
 	* time/Makefile: Rewrite rules for test to handle parallel builds.
 
diff --git a/FAQ b/FAQ
index 68043f8d9b..c7d6445ea6 100644
--- a/FAQ
+++ b/FAQ
@@ -550,7 +550,8 @@ by
 
 in the above example specs file to make it work for other systems.
 
-Future versions of GCC will automatically provide the correct specs.
+Version 2.7.2.2 does and future versions of GCC will automatically
+provide the correct specs.
 
 
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -597,10 +598,22 @@ invalid.  I.e., an emulated FPU is for the libc as good as a real one.
 [Q20]	``How can I compile gcc 2.7.2.1 from the gcc source code using
 	  glibc 2.x?
 
-[A20] {HJL} There is no support in gcc for glibc 2.0 before gcc 2.8. It
-is very tricky to compile gcc 2.7.2.1 using glibc 2.x. You have to
-build it manually or with one pass only. You also have to use the
-specs file in this FAQ while compiling gcc.
+[A20] {AJ} There's only support for glibc 2.0 in gcc 2.7.2.2 or later.
+For 2.7.2.2 you should use the following patch and configure for
+e.g. i486-linux.
+-----------------------------------------------------------------------
+--- configure       Tue Feb 11 15:57:17 1997
++++ configure   Wed Feb 12 23:09:29 1997
+@@ -1021,7 +1021,7 @@
+                gnu_ld=yes
+                # GNU libc version 2 does not supply these;
+                # we want them from GCC.
+-               extra_parts="crtbegin.o crtend.o"
++               extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS..o"
+                ;;
+         i[3456]86-go32-msdos | i[3456]86-*-go32)
+               cpu_type=i386
+-----------------------------------------------------------------------
 
 
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
diff --git a/INSTALL b/INSTALL
index e82b645b41..3c172a280b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -76,6 +76,23 @@ you run `configure':
      static library is compiled with no optimization and full debugging
      information, and installed as `-lc_g'.
 
+`--enable-bounded'
+`--disable-bounded'
+     Enable or disable building of the C library with support for bounded
+     pointers.  To do this one need the enhanced version of the GNU CC
+     with can generate code for bounded pointers.  This version of the
+     C library is necessary to run code which is also compiled using the
+     enhanced gcc for debugging purposes.
+
+There are two more options:
+
+`--with-gmp'
+`--with-gettext'
+     These options are not of much use for the normal installer of the
+     GNU libc.  Only maintainers need this to get automatic updates of
+     the files from these packages in the GNU C library source tree.
+
+
    The simplest way to run `configure' is to do it in the directory
 that contains the library sources.  This prepares to build the library
 in that very directory.
@@ -182,6 +199,9 @@ following patterns:
      iX86-ANYTHING-gnu
      iX86-ANYTHING-linux
      m68k-ANYTHING-linux
+     mips-ANYTHING-linux
+     sparc-ANYTHING-linux
+     powerpc-ANYTHING-linux
 
    Former versions of this library used to support the following
 configurations but the current status is unknown:
@@ -208,7 +228,7 @@ configurations but the current status is unknown:
      sparc-sun-solaris2.N
      sparc-sun-sunos4.N
 
-   Each case of `iX86' can be `i386', `i486', `i586', or `i686'..  All
+   Each case of `iX86' can be `i386', `i486', `i586', or `i686'.  All
 of those configurations produce a library that can run on any of these
 processors.  The library will be optimized for the specified processor,
 but will not use instructions not available on all of them.
@@ -652,10 +672,10 @@ level of the `sysdeps' hierarchy.  This directory contains
 subdirectories (and subdirectory trees) for various Unix variants.
 
    The functions which are system calls in most Unix systems are
-implemented in assembly code in files in `sysdeps/unix'.  These files
-are named with a suffix of `.S'; for example, `__open.S'.  Files ending
-in `.S' are run through the C preprocessor before being fed to the
-assembler.
+automatically generated from the `syscalls.list' files for the appropriate
+archirecture.  The format of the syscalls.list files is quite easy: only
+a few informations are necessary line the system call name, the number of
+arguments and such.  The files are run through the C preprocessor.
 
    These files all use a set of macros that should be defined in
 `sysdep.h'.  The `sysdep.h' file in `sysdeps/unix' partially defines
diff --git a/Makeconfig b/Makeconfig
index d004e07acc..cd0e4799a1 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -239,7 +239,8 @@ endif
 # other than there, so the zoneinfo directory contains only universal data,
 # localizing the configuration data elsewhere.
 ifndef localtime-file
-localtime-file = $(inst_sysconfdir)/localtime
+localtime-file = $(sysconfdir)/localtime
+inst_localtime-file = $(install_root)$(localtime-file)
 endif
 
 # What to use for leap second specifications in compiling the default
@@ -490,9 +491,6 @@ object-suffixes += .so
 CPPFLAGS-.so = -DPIC
 CFLAGS-.so = -fPIC -fno-common
 libtype.so := lib%_pic.a
-ifndef ASFLAGS-.so
-ASFLAGS-.so =
-endif
 endif
 ifeq (yes,$(build-profile))
 # Under --enable-profile, we will build a static library of profiled objects.
@@ -501,9 +499,6 @@ object-suffixes += .po
 CPPFLAGS-.po = -DPROF
 CFLAGS-.po = -pg
 libtype.po = lib%_p.a
-ifndef ASFLAGS-.po
-ASFLAGS-.po =
-endif
 endif
 ifeq (yes,$(build-omitfp))
 # Under --enable-omitfp, we build an the library optimized without
@@ -514,9 +509,6 @@ CFLAGS-.go = -g
 CFLAGS-.o = -g0 -O99 -fomit-frame-pointer
 CFLAGS-.so += $(CFLAGS-.o)
 libtype.go = lib%_g.a
-ifndef ASFLAGS-.go
-ASFLAGS-.go =
-endif
 endif
 ifeq (yes,$(build-bounded))
 # Under --enable-bounded, we build the library with `-fbounded-pointers -g'
@@ -525,9 +517,6 @@ object-suffixes += .bo
 CPPFLAGS-.bo = -DBOUNDED_POINTERS
 CFLAGS-.bo = -g -fbounded-pointers
 libtype.bo = lib%_b.a
-ifndef ASFLAGS-.bo
-ASFLAGS-.bo =
-endif
 endif
 
 
diff --git a/Makerules b/Makerules
index 7a99001c8e..26e272e3aa 100644
--- a/Makerules
+++ b/Makerules
@@ -363,6 +363,8 @@ $(LINK.o) -shared -o $@ $(sysdep-LDFLAGS) $(config-LDFLAGS)  \
 	  -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
 	  -Wl,--whole-archive $^ $(no-whole-archive) \
 	  $(LDLIBS-$(@F:lib%.so=%).so)
+	  test -z "$($(@F)-version)" || \
+	    (rm -f $@$($(@F)-version); $(LN_S) $(@F) $@$($(@F)-version))
 endef
 
 # Don't try to use -lc when making libc.so itself.
@@ -378,12 +380,6 @@ $(common-objpfx)libc.so: $(elfobjdir)/soinit.so \
 			 $(common-objpfx)libc_pic.a \
 			 $(elfobjdir)/sofini.so $(elfobjdir)/ld.so
 	$(build-shlib)
-
-ifdef libc.so-version
-$(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
-	rm -f $@
-	ln -s $(<F) $@ || ln $< $@
-endif
 endif
 
 # Some files must not be compiled with the exception handler mechanism
diff --git a/catgets/catgets.c b/catgets/catgets.c
index a9425e4091..9228f970d6 100644
--- a/catgets/catgets.c
+++ b/catgets/catgets.c
@@ -84,8 +84,17 @@ catopen (const char *cat_name, int flag)
 	}
 
       nlspath = __secure_getenv ("NLSPATH");
-      result->nlspath = __strdup (nlspath != NULL && *nlspath != '\0'
-				  ? nlspath : NLSPATH);
+      if (nlspath != NULL && *nlspath != '\0')
+	{
+	  /* Append the system dependent directory.  */
+	  size_t len = strlen (nlspath + 1 + sizeof NLSPATH);
+	  char *tmp = alloca (len);
+
+	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
+	  nlspath = tmp;
+	}
+      else
+	result->nlspath = __strdup (NLSPATH);
 
       if (result->nlspath == NULL)
 	{
diff --git a/config.make.in b/config.make.in
index 8f72139361..0a7d0379fd 100644
--- a/config.make.in
+++ b/config.make.in
@@ -51,9 +51,6 @@ AR = @AR@
 RANLIB = @RANLIB@
 AS = $(CC) -c
 
-# Build tool flags.
-ASFLAGS-.so = @ASFLAGS_SO@
-
 # Installation tools.
 INSTALL = @INSTALL@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/configure b/configure
index 1dd8a6adb2..3edb97d984 100755
--- a/configure
+++ b/configure
@@ -2037,8 +2037,6 @@ fi
 
 
 
-
-
 if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
   config_makefile=
 else
@@ -2225,7 +2223,6 @@ s%@profile@%$profile%g
 s%@omitfp@%$omitfp%g
 s%@bounded@%$bounded%g
 s%@DEFINES@%$DEFINES%g
-s%@ASFLAGS_SO@%$ASFLAGS_SO%g
 s%@VERSION@%$VERSION%g
 
 CEOF
diff --git a/configure.in b/configure.in
index 44147caf0b..f36bcaf1bf 100644
--- a/configure.in
+++ b/configure.in
@@ -810,8 +810,6 @@ AC_SUBST(bounded)
 
 AC_SUBST(DEFINES)
 
-AC_SUBST(ASFLAGS_SO)
-
 if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
   config_makefile=
 else
diff --git a/db/hash/hash_bigkey.c b/db/hash/hash_bigkey.c
index d2a7dfd597..d80ebedb07 100644
--- a/db/hash/hash_bigkey.c
+++ b/db/hash/hash_bigkey.c
@@ -249,7 +249,7 @@ __big_delete(hashp, bufp)
 	bufp->flags |= BUF_MOD;
 	if (rbufp)
 		__free_ovflpage(hashp, rbufp);
-	if (last_bfp != rbufp)
+	if (last_bfp && last_bfp != rbufp)
 		__free_ovflpage(hashp, last_bfp);
 
 	hashp->NKEYS--;
diff --git a/dirent/alphasort.c b/dirent/alphasort.c
index 6c62380e99..95e0da056c 100644
--- a/dirent/alphasort.c
+++ b/dirent/alphasort.c
@@ -22,6 +22,6 @@
 int
 alphasort (const void *a, const void *b)
 {
-  return strcmp (((struct dirent *) a)->d_name,
-		 ((struct dirent *) b)->d_name);
+  return strcmp ((*(const struct dirent **) a)->d_name,
+		 (*(const struct dirent **) b)->d_name);
 }
diff --git a/elf/rtld.c b/elf/rtld.c
index 9f18e23b91..15df75fe8b 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -126,10 +126,6 @@ _dl_start (void *arg)
 			_dl_rtld_map.l_info[DT_STRTAB]->d_un.d_ptr +
 			_dl_rtld_map.l_info[DT_RPATH]->d_un.d_val);
 
-#ifdef ELF_ADJUST_ARG
-  ELF_ADJUST_ARG(arg);
-#endif
-
   /* Call the OS-dependent function to set up life so we can do things like
      file access.  It will call `dl_main' (below) to do all the real work
      of the dynamic linker, and then unwind our frame and run the user
diff --git a/hurd/hurd.h b/hurd/hurd.h
index 7e72bf6cf3..eb445d481a 100644
--- a/hurd/hurd.h
+++ b/hurd/hurd.h
@@ -303,4 +303,11 @@ extern int hurd_check_cancel (void);
 extern io_t __getdport (int fd), getdport (int fd);
 
 
+#include <stdarg.h>
+
+/* Write formatted output to PORT, a Mach port supporting the i/o protocol,
+   according to the format string FORMAT, using the argument list in ARG.  */
+int vpprintf (io_t port, const char *format, va_list arg);
+
+
 #endif	/* hurd.h */
diff --git a/hurd/set-host.c b/hurd/set-host.c
index 5c905d8f04..eee50fc08e 100644
--- a/hurd/set-host.c
+++ b/hurd/set-host.c
@@ -28,7 +28,7 @@ _hurd_set_host_config (const char *item, const char *value, size_t valuelen)
   mach_msg_type_number_t nwrote;
   file_t new, dir;
 
-  dir = __file_name_split (item, &item);
+  dir = __file_name_split (item, (char **)&item);
   if (dir == MACH_PORT_NULL)
     return -1;
 
diff --git a/hurd/vpprintf.c b/hurd/vpprintf.c
index 8ec064ae41..fe521774ea 100644
--- a/hurd/vpprintf.c
+++ b/hurd/vpprintf.c
@@ -22,10 +22,9 @@
 #include <hurd.h>
 
 static ssize_t
-pwrite (cookie, buf, n)
-     void *cookie;
-     const char *buf;
-     size_t n;
+pwrite (void *cookie,
+	const char *buf,
+	size_t n)
 {
   error_t error = __io_write ((io_t) cookie, buf, n, -1,
 			      (mach_msg_type_number_t *) &n);
@@ -38,10 +37,9 @@ pwrite (cookie, buf, n)
 /* Write formatted output to PORT, a Mach port supporting the i/o protocol,
    according to the format string FORMAT, using the argument list in ARG.  */
 int
-vpprintf (port, format, arg)
-     io_t port;
-     const char *format;
-     va_list arg;
+vpprintf (io_t port,
+	  const char *format,
+	  va_list arg)
 {
   int done;
   FILE f;
diff --git a/inet/rcmd.c b/inet/rcmd.c
index 0ee0c5d17f..342c1c909e 100644
--- a/inet/rcmd.c
+++ b/inet/rcmd.c
@@ -306,7 +306,6 @@ iruserok(raddr, superuser, ruser, luser)
 	struct stat sbuf;
 	struct passwd pwdbuf, *pwd;
 	FILE *hostf;
-	uid_t uid;
 	int first;
 
 	first = 1;
@@ -342,7 +341,12 @@ again:
 		if (__euidaccess (pbuf, R_OK) != 0)
 		  hostf = NULL;
 		else
-		  hostf = fopen(pbuf, "r");
+		  {
+		    uid_t uid = geteuid ();
+		    seteuid (pwd->pw_uid);
+		    hostf = fopen (pbuf, "r");
+		    seteuid (uid);
+		  }
 
 		if (hostf == NULL)
 			return (-1);
diff --git a/mach/error_compat.c b/mach/error_compat.c
index 0498f017ba..e874dd43d4 100644
--- a/mach/error_compat.c
+++ b/mach/error_compat.c
@@ -26,6 +26,25 @@
 
 /* This file was broken out from:
 	$Log$
+	Revision 1.2  1997/03/16 17:41:36  drepper
+	(__mach_error_map_compat): Give full prototype.
+
+	Revision 1.2  1997/03/14 15:26:28  thomas
+	Wed Mar  5 10:40:05 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+		* mach/mach_error.c (mach_error_string_int): Give full prototype.
+		* mach/errstring.c (mach_error_string_int): Likewise.
+		* mach/error_compat.c (__mach_error_map_compat): Likewise.
+
+		* mach/spin-solid.c: Include <mach/mach_traps.h>.
+		* mach/spin-solid.c (__spin_lock_solid): Provide arg to
+		swtch_pri.
+
+		* mach/mach_init.c: Include <mach/mig_support.h>.
+
+		* mach/mach_error.h (mach_error_string, mach_error,
+		mach_error_type): Always provide prototypes.
+
 	Revision 1.1  1993/11/30 17:35:24  roland
 	entered into RCS
 
@@ -39,8 +58,7 @@
 
 
 void
-__mach_error_map_compat( org_err )
-	mach_error_t		* org_err;
+__mach_error_map_compat(mach_error_t  *org_err)
 {
 	mach_error_t		err = *org_err;
 
diff --git a/mach/errstring.c b/mach/errstring.c
index 761a615e29..e56fa728cc 100644
--- a/mach/errstring.c
+++ b/mach/errstring.c
@@ -26,6 +26,25 @@
 /*
  * HISTORY
  * $Log$
+ * Revision 1.2  1997/03/16 17:41:48  drepper
+ * (mach_error_string_int): Give full prototype.
+ *
+ * Revision 1.2  1997/03/14 15:26:29  thomas
+ * Wed Mar  5 10:40:05 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+ *
+ * 	* mach/mach_error.c (mach_error_string_int): Give full prototype.
+ * 	* mach/errstring.c (mach_error_string_int): Likewise.
+ * 	* mach/error_compat.c (__mach_error_map_compat): Likewise.
+ *
+ * 	* mach/spin-solid.c: Include <mach/mach_traps.h>.
+ * 	* mach/spin-solid.c (__spin_lock_solid): Provide arg to
+ * 	swtch_pri.
+ *
+ * 	* mach/mach_init.c: Include <mach/mig_support.h>.
+ *
+ * 	* mach/mach_error.h (mach_error_string, mach_error,
+ * 	mach_error_type): Always provide prototypes.
+ *
  * Revision 1.1  1993/11/30 17:35:58  roland
  * entered into RCS
  *
@@ -67,9 +86,8 @@ mach_error_type( err )
 boolean_t mach_error_full_diag = FALSE;
 
 const char *
-mach_error_string_int( err, diag )
-	mach_error_t		err;
-	boolean_t		* diag;
+mach_error_string_int(mach_error_t	err,
+		      boolean_t		* diag)
 {
 	int sub, system, code;
 
diff --git a/mach/mach/error.h b/mach/mach/error.h
index 83cf61ef8f..70f189f65e 100644
--- a/mach/mach/error.h
+++ b/mach/mach/error.h
@@ -27,6 +27,18 @@
 /*
  * HISTORY
  * $Log$
+ * Revision 1.3  1997/03/16 17:43:08  drepper
+ * (mach_error_fn_t): Comment out declaration; it appears to be entirely
+ * unused dead code.
+ *
+ * Revision 1.3  1997/03/14 15:27:35  thomas
+ * Wed Mar  5 10:40:05 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+ *
+ * 	* mach/mach/mach_traps.h: Include <mach/kern_return.h>.
+ *
+ * 	* mach/mach/error.h (mach_error_fn_t): Comment out declaration; it
+ * 	appears to be entirely unused dead code.
+ *
  * Revision 1.2  1996/12/20 01:32:36  drepper
  * Update from main archive 961219
  *
@@ -141,6 +153,6 @@
 #define	unix_err(errno)		(err_kern|err_sub(3)|errno)
 
 typedef	kern_return_t	mach_error_t;
-typedef mach_error_t	(* mach_error_fn_t)();
+/* typedef mach_error_t	(* mach_error_fn_t)(); */
 
 #endif	/* _MACH_ERROR_H_ */
diff --git a/mach/mach/mach_traps.h b/mach/mach/mach_traps.h
index 17fee75fae..fbd92dd310 100644
--- a/mach/mach/mach_traps.h
+++ b/mach/mach/mach_traps.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -26,7 +26,7 @@
 #define _MACH_MACH_TRAPS_H_	1
 
 #include <mach/port.h>
-
+#include <mach/kern_return.h>
 
 /* Create and return a new receive right.  */
 extern mach_port_t mach_reply_port (void);
diff --git a/mach/mach_error.c b/mach/mach_error.c
index 6cac0a5a7c..f6f945fd73 100644
--- a/mach/mach_error.c
+++ b/mach/mach_error.c
@@ -26,6 +26,25 @@
 /*
  * HISTORY
  * $Log$
+ * Revision 1.2  1997/03/16 17:42:02  drepper
+ * (mach_error_string_int): Give full prototype.
+ *
+ * Revision 1.2  1997/03/14 15:26:30  thomas
+ * Wed Mar  5 10:40:05 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+ *
+ * 	* mach/mach_error.c (mach_error_string_int): Give full prototype.
+ * 	* mach/errstring.c (mach_error_string_int): Likewise.
+ * 	* mach/error_compat.c (__mach_error_map_compat): Likewise.
+ *
+ * 	* mach/spin-solid.c: Include <mach/mach_traps.h>.
+ * 	* mach/spin-solid.c (__spin_lock_solid): Provide arg to
+ * 	swtch_pri.
+ *
+ * 	* mach/mach_init.c: Include <mach/mig_support.h>.
+ *
+ * 	* mach/mach_error.h (mach_error_string, mach_error,
+ * 	mach_error_type): Always provide prototypes.
+ *
  * Revision 1.1  1992/10/06 18:29:54  roland
  * entered into RCS
  *
@@ -63,7 +82,7 @@
 #include <mach_error.h>
 #include <mach/boolean.h>
 
-extern char * mach_error_string_int();
+extern char * mach_error_string_int(mach_error_t, boolean_t *);
 
 void
 mach_error( str, err )	
diff --git a/mach/mach_error.h b/mach/mach_error.h
index 852ab4e622..f88d1732e8 100644
--- a/mach/mach_error.h
+++ b/mach/mach_error.h
@@ -26,6 +26,28 @@
 /*
  * HISTORY
  * $Log$
+ * Revision 1.3  1997/03/16 17:42:25  drepper
+ * (mach_error_string, mach_error, mach_error_type): Always provide
+ * prototypes.
+ * (mach_error_fn_t): Comment out declaration; it appears to be entirely
+ * unused dead code.
+ *
+ * Revision 1.3  1997/03/14 15:26:31  thomas
+ * Wed Mar  5 10:40:05 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+ *
+ * 	* mach/mach_error.c (mach_error_string_int): Give full prototype.
+ * 	* mach/errstring.c (mach_error_string_int): Likewise.
+ * 	* mach/error_compat.c (__mach_error_map_compat): Likewise.
+ *
+ * 	* mach/spin-solid.c: Include <mach/mach_traps.h>.
+ * 	* mach/spin-solid.c (__spin_lock_solid): Provide arg to
+ * 	swtch_pri.
+ *
+ * 	* mach/mach_init.c: Include <mach/mig_support.h>.
+ *
+ * 	* mach/mach_error.h (mach_error_string, mach_error,
+ * 	mach_error_type): Always provide prototypes.
+ *
  * Revision 1.2  1993/11/23 20:39:08  mib
  * entered into RCS
  *
@@ -53,28 +75,22 @@ const char	*mach_error_string(
 /*
  *	Returns a string appropriate to the error argument given
  */
-#if	c_plusplus
 	mach_error_t error_value
-#endif	c_plusplus
 				);
 
 void		mach_error(
 /*
  *	Prints an appropriate message on the standard error stream
  */
-#if	c_plusplus
 	char 		*str,
 	mach_error_t	error_value
-#endif	c_plusplus
 				);
 
 const char	*mach_error_type(
 /*
  *	Returns a string with the error system, subsystem and code
 */
-#if	c_plusplus
 	mach_error_t	error_value
-#endif  c_plusplus
 				);
 
 #endif	_MACH_ERROR_
diff --git a/mach/mach_init.c b/mach/mach_init.c
index db340fff2d..eb8ed9b046 100644
--- a/mach/mach_init.c
+++ b/mach/mach_init.c
@@ -18,6 +18,7 @@
 
 #include <mach_init.h>
 #include <mach/mach_interface.h>
+#include <mach/mig_support.h>
 
 mach_port_t __mach_task_self_;
 vm_size_t __vm_page_size = 0;	/* Must be data not bss for weak alias.  */
diff --git a/mach/spin-solid.c b/mach/spin-solid.c
index a98578552e..93f6ff79e4 100644
--- a/mach/spin-solid.c
+++ b/mach/spin-solid.c
@@ -17,12 +17,13 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <spin-lock.h>
+#include <mach/mach_traps.h>
 
 void
 __spin_lock_solid (spin_lock_t *lock)
 {
   while (__spin_lock_locked (lock) || ! __spin_try_lock (lock))
     /* Yield to another thread (system call).  */
-    __swtch_pri ();
+    __swtch_pri (0);
 }
 weak_alias (__spin_lock_solid, spin_lock_solid);
diff --git a/manual/examples/dir2.c b/manual/examples/dir2.c
new file mode 100644
index 0000000000..e3157694bd
--- /dev/null
+++ b/manual/examples/dir2.c
@@ -0,0 +1,29 @@
+/*@group*/
+#include <stdio.h>
+#include <dirent.h>
+/*@end group*/
+
+static int
+one (struct dirent *unused)
+{
+  return 1;
+}
+
+int
+main (void)
+{
+  struct dirent **eps;
+  int n;
+
+  n = scandir ("./", &eps, one, alphasort);
+  if (n >= 0)
+    {
+      int cnt;
+      for (cnt = 0; cnt < n; ++cnt)
+	puts (eps[cnt]->d_name);
+    }
+  else
+    perror ("Couldn't open the directory");
+
+  return 0;
+}
diff --git a/manual/filesys.texi b/manual/filesys.texi
index f5d94b9732..afe072c594 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -166,6 +166,9 @@ parallels here to the stream facilities for ordinary files, described in
 * Simple Directory Lister::     A very simple directory listing program.
 * Random Access Directory::     Rereading part of the directory
                                  already read with the same stream.
+* Scanning Directory Content::  Get entries for user selected subset of
+                                 contents in given directory.
+* Simple Directory Lister Mark II::  Revised version of the program.
 @end menu
 
 @node Directory Entries
@@ -386,9 +389,9 @@ the current working directory:
 
 The order in which files appear in a directory tends to be fairly
 random.  A more useful program would sort the entries (perhaps by
-alphabetizing them) before printing them; see @ref{Array Sort Function}.
+alphabetizing them) before printing them; see
+@ref{Scanning Directory Content} and @ref{Array Sort Function}.
 
-@c ??? not documented: scandir, alphasort
 
 @node Random Access Directory
 @subsection Random Access in a Directory Stream
@@ -429,6 +432,69 @@ closing and reopening the directory can invalidate values returned by
 @code{telldir}.
 @end deftypefun
 
+
+@node Scanning Directory Content
+@subsection Scanning the Content of a Directory
+
+A higher-level interface to the directory handling functions is the
+@code{scandir} function.  With its help one can select a subset of the
+entries in a directory, possibly sort them and get as the result a list
+of names.
+
+@deftypefun int scandir (const char *@var{dir}, struct dirent ***@var{namelist}, int (*@var{selector}) (struct dirent *), int (*@var{cmp}) (const void *, const void *))
+
+The @code{scandir} function scans the contents of the directory selected
+by @var{dir}.  The result in @var{namelist} is an array of pointers to
+structure of type @code{struct dirent} which describe all selected
+directory entries and which is allocated using @code{malloc}.  Instead
+of always getting all directory entries returned, the user supplied
+function @var{selector} can be used to decide which entries are in the
+result.  Only the entries for which @var{selector} returns a nonzero
+value are selected.
+
+Finally the entries in the @var{namelist} are sorted using the user
+supplied function @var{cmp}.  The arguments of the @var{cmp} function
+are of type @code{struct dirent **}.  I.e., one cannot directly use the
+@code{strcmp} or @code{strcoll} function; see the function
+@code{alphasort} below.
+
+The return value of the function gives the number of entries placed in
+@var{namelist}.  If it is @code{-1} an error occurred and the global
+variable @code{errno} contains more information on the error.
+@end deftypefun
+
+As said above the fourth argument to the @code{scandir} function must be
+a pointer to a sorting function.  For the convenience of the programmer
+the GNU C library contains an implementation of a function which is very
+helpful for this purpose.
+
+@deftypefun int alphasort (const void *@var{a}, const void *@var{b})
+The @code{alphasort} function behaves like the @code{strcmp} function
+(@pxref{String/Array Comparison}).  The difference is that the arguments
+are not string pointers but instead they are of type
+@code{struct dirent **}.
+
+Return value of is less than, equal to, or greater than zero depending
+on the order of the two entries @var{a} and @var{b}.
+@end deftypefun
+
+@node Simple Directory Lister Mark II
+@subsection Simple Program to List a Directory, Mark II
+
+Here is a revised version of the directory lister found above
+(@pxref{Simple Directory Lister}).  Using the @code{scandir} function we
+can avoid using the functions which directly work with the directory
+contents.  After the call the found entries are available for direct
+used.
+
+@smallexample
+@include dir2.c.texi
+@end smallexample
+
+Please note the simple selector function for this example.  Since
+we want to see all directory entries we always return @code{1}.
+
+
 @node Hard Links
 @section Hard Links
 @cindex hard link
diff --git a/manual/math.texi b/manual/math.texi
index 61455ef8a8..543647297f 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -83,23 +83,23 @@ mathematical @code{double} returning functions in overflow situations.
 @end deftypevr
 
 @comment math.h
-@comment GNU
-@deftypevr Macro float HUGE_VALf
+@comment ISO
+@deftypevr Macro float HUGE_VALF
 This macro is similar to the @code{HUGE_VAL} macro except that it is
 used by functions returning @code{float} values.
 
-This macro is a GNU extension.
+This macro is introduced in @w{ISO C 9X}.
 @end deftypevr
 
 @comment math.h
-@comment GNU
-@deftypevr Macro {long double} HUGE_VALl
+@comment ISO
+@deftypevr Macro {long double} HUGE_VALL
 This macro is similar to the @code{HUGE_VAL} macro except that it is
 used by functions returning @code{long double} values.  The value is
 only different from @code{HUGE_VAL} if the architecture really supports
 @code{long double} values.
 
-This macro is a GNU extension.
+This macro is introduced in @w{ISO C 9X}.
 @end deftypevr
 
 
diff --git a/math/libm-test.c b/math/libm-test.c
new file mode 100644
index 0000000000..98e3cbad5d
--- /dev/null
+++ b/math/libm-test.c
@@ -0,0 +1,1520 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@arthur.pfalz.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+
+/*
+   Part of testsuite for libm.
+
+   This file has to be included by a master file that defines:
+
+   Makros:
+   FUNC(function): converts general function name (like cos) to
+   name with correct suffix (e.g. cosl or cosf)
+   MATHCONST(x):   like FUNC but for constants (e.g convert 0.0 to 0.0L)
+   MATHTYPE:       floating point type to test
+   TEST_MSG:       informal message to be displayed
+   CHOOSE(Clongdouble,Cdouble,Cfloat):
+   chooses one of the parameters as epsilon for testing
+   equality
+   PRINTF_EXPR     Floating point conversion specification to print a variable
+   of type MATHTYPE with printf. PRINTF_EXPR just contains
+   the specifier, not the percent and width arguments,
+   e.g. "f"
+ */
+
+/* This program isn't finished yet.
+   It has tests for acos, acosh, asin, asinh, atan, atan2, atanh,
+   cbrt, ceil, cos, cosh, exp, exp2, expm1, fabs, floor, fpclassify,
+   frexp, ldexp,
+   log, log10, log1p, log2, logb,
+   pow, sin, sinh, tan, tanh, fabs, hypot.
+   Tests for the other libm-functions will come later.
+
+   The routines using random variables are still under construction. I don't
+   like it the way it's working now and will change it.
+
+   Exception handling has not been implemented so far so don't get fooled
+   that these tests pass.
+
+   Parameter handling is primitive in the moment:
+   --verbose=[0..3] for different levels of output:
+   0: only error count
+   1: basic report on failed tests
+   2: full report on failed tests
+   3: full report on failed and passed tests (default)
+   -v for full output (equals --verbose=3)
+   -s,--silent outputs only the error count (equals --verbose=0)
+ */
+
+/* Define if the following ISO C 9X functions are implemented: exp2,
+   log2.  */
+#undef ISO_9X_IMPLEMENTED
+
+#define _GNU_SOURCE
+
+#include <math.h>
+#include <float.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <getopt.h>
+
+/* TEST_EXCEPTION: tests if an exception as occured */
+/* for the moment: does nothing */
+/* Possible exceptions */
+#define NO_EXCEPTION             0x0
+#define INVALID_EXCEPTION        0x1
+#define DIVIDE_BY_ZERO_EXCEPTION 0x2
+
+#define PRINT 1
+#define NO_PRINT 0
+
+#define TEST_EXCEPTION(test) do {} while (0);
+/* As long as no exception code is available prevent warnings.  */
+#define UNUSED __attribute__ ((unused))
+
+static int noErrors;
+
+static int verbose = 3;
+static MATHTYPE minus_zero, plus_zero;
+static MATHTYPE plus_infty, minus_infty, nan_value;
+
+typedef MATHTYPE (*mathfunc) (MATHTYPE);
+
+
+#define ISINF(x)                                \
+(sizeof (x) == sizeof (float) ?                 \
+ isinff (x)                                   \
+ : sizeof (x) == sizeof (double) ?              \
+ isinf (x) : isinfl (x))
+
+
+     /*
+        Test if Floating-Point stack hasn't changed
+      */
+static void
+fpstack_test (const char *test_name)
+{
+#ifdef i386
+  static int old_stack;
+  int sw;
+asm ("fnstsw":"=a" (sw));
+  sw >>= 11;
+  sw &= 7;
+  if (sw != old_stack)
+    {
+      printf ("FP-Stack wrong after test %s\n", test_name);
+      if (verbose > 2)
+	printf ("=======> stack = %d\n", sw);
+      ++noErrors;
+      old_stack = sw;
+    }
+#endif
+}
+
+
+/*
+   Call to an external function so that floating point registers
+   get moved to memory
+ */
+static void
+this_does_nothing (void)
+{
+  clock_t dummy;
+
+  dummy = clock ();
+}
+
+/*
+   Get a random value x with min_value < x < max_value
+   and min_value, max_value finite,
+   max_value and min_value shouldn't be too close together
+ */
+static MATHTYPE
+random_value (MATHTYPE min_value, MATHTYPE max_value)
+{
+  int r;
+  MATHTYPE x;
+
+  r = rand ();
+
+  x = (max_value - min_value) / RAND_MAX * (MATHTYPE) r + min_value;
+
+  if ((x <= min_value) || (x >= max_value) || !isfinite (x))
+    x = (max_value - min_value) / 2 + min_value;
+
+  return x;
+}
+
+/* Get a random value x with x > min_value.  */
+static MATHTYPE
+random_greater (MATHTYPE min_value)
+{
+  return random_value (min_value, 1e6);		/* CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX) */
+}
+
+/* Get a random value x with x < max_value.  */
+static MATHTYPE
+random_less (MATHTYPE max_value)
+{
+  return random_value (-1e6, max_value);
+}
+
+
+/* Test if two floating point numbers are equal.  */
+static int
+check_equal (MATHTYPE computed, MATHTYPE supplied, MATHTYPE eps, MATHTYPE * diff)
+{
+  /* Both plus Infinity or both minus infinity.  */
+  if (ISINF (computed) && (ISINF (computed) == ISINF (supplied)))
+    return 1;
+
+  if (isnan (computed) && isnan (supplied))	/* isnan works for all types */
+    return 1;
+
+  *diff = FUNC(fabs) (computed - supplied);
+
+  if (*diff <= eps || signbit (computed) != signbit (supplied))
+    return 1;
+
+  return 0;
+}
+
+
+static void
+output_result_bool (const char *test_name, int result)
+{
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      noErrors++;
+    }
+
+  fpstack_test (test_name);
+}
+
+
+static void
+output_isvalue (const char *test_name, int result,
+		MATHTYPE value)
+{
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      if (verbose > 1)
+	printf (" Value: %.20" PRINTF_EXPR "\n", value);
+      noErrors++;
+    }
+
+  fpstack_test (test_name);
+}
+
+
+static void
+output_isvalue_ext (const char *test_name, int result,
+		    MATHTYPE value, MATHTYPE parameter)
+{
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      if (verbose > 1)
+	{
+	  printf (" Value:     %.20" PRINTF_EXPR "\n", value);
+	  printf (" Parameter: %.20" PRINTF_EXPR "\n", parameter);
+	}
+      noErrors++;
+    }
+
+  fpstack_test (test_name);
+}
+
+
+static void
+output_result (const char *test_name, int result,
+	       MATHTYPE computed, MATHTYPE expected,
+	       MATHTYPE difference,
+	       int print_values, int print_diff)
+{
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      if (verbose > 1 && print_values)
+	{
+	  printf ("Result:\n");
+	  printf (" is:         %.20" PRINTF_EXPR "\n", computed);
+	  printf (" should be:  %.20" PRINTF_EXPR "\n", expected);
+	  if (print_diff)
+	    printf (" difference: %.20" PRINTF_EXPR "\n", difference);
+	}
+      noErrors++;
+    }
+
+  fpstack_test (test_name);
+}
+
+
+static void
+output_result_ext (const char *test_name, int result,
+		   MATHTYPE computed, MATHTYPE expected,
+		   MATHTYPE difference,
+		   MATHTYPE parameter,
+		   int print_values, int print_diff)
+{
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      if (verbose > 1 && print_values)
+	{
+	  printf ("Result:\n");
+	  printf (" is:         %.20" PRINTF_EXPR "\n", computed);
+	  printf (" should be:  %.20" PRINTF_EXPR "\n", expected);
+	  if (print_diff)
+	    printf (" difference: %.20" PRINTF_EXPR "\n", difference);
+	  printf ("Parameter:   %.20" PRINTF_EXPR "\n", parameter);
+	}
+      noErrors++;
+    }
+
+  fpstack_test (test_name);
+}
+
+
+static void
+check (const char *test_name, MATHTYPE computed, MATHTYPE expected)
+{
+  MATHTYPE diff;
+  int result;
+
+  result = check_equal (computed, expected, 0, &diff);
+  output_result (test_name, result,
+		 computed, expected, diff, PRINT, PRINT);
+}
+
+
+static void
+check_ext (const char *test_name, MATHTYPE computed, MATHTYPE expected,
+	   MATHTYPE parameter)
+{
+  MATHTYPE diff;
+  int result;
+
+  result = check_equal (computed, expected, 0, &diff);
+  output_result_ext (test_name, result,
+		     computed, expected, diff, parameter, PRINT, PRINT);
+}
+
+
+static void
+check_eps (const char *test_name, MATHTYPE computed, MATHTYPE expected,
+	   MATHTYPE epsilon)
+{
+  MATHTYPE diff;
+  int result;
+
+  result = check_equal (computed, expected, epsilon, &diff);
+  output_result (test_name, result,
+		 computed, expected, diff, PRINT, PRINT);
+}
+
+
+static void
+check_bool (const char *test_name, int computed)
+{
+  output_result_bool (test_name, computed);
+}
+
+
+static void
+check_isnan (const char *test_name, MATHTYPE computed)
+{
+  output_isvalue (test_name, isnan (computed), computed);
+}
+
+
+static void
+check_isnan_exc (const char *test_name, MATHTYPE computed,
+		 short exception UNUSED)
+{
+  output_isvalue (test_name, isnan (computed), computed);
+}
+
+
+static void
+check_isnan_ext (const char *test_name, MATHTYPE computed,
+		 MATHTYPE parameter)
+{
+  output_isvalue_ext (test_name, isnan (computed), computed, parameter);
+}
+
+
+/* Tests if computed is +Inf */
+static void
+check_isinfp (const char *test_name, MATHTYPE computed)
+{
+  output_isvalue (test_name, (ISINF (computed) == +1), computed);
+}
+
+
+static void
+check_isinfp_ext (const char *test_name, MATHTYPE computed,
+		  MATHTYPE parameter)
+{
+  output_isvalue_ext (test_name, (ISINF (computed) == +1), computed, parameter);
+}
+
+
+/* Tests if computed is +Inf */
+static void
+check_isinfp_exc (const char *test_name, MATHTYPE computed,
+		  int exception UNUSED)
+{
+  output_isvalue (test_name, (ISINF (computed) == +1), computed);
+}
+
+/* Tests if computed is -Inf */
+static void
+check_isinfn (const char *test_name, MATHTYPE computed)
+{
+  output_isvalue (test_name, (ISINF (computed) == -1), computed);
+}
+
+
+static void
+check_isinfn_ext (const char *test_name, MATHTYPE computed,
+		  MATHTYPE parameter)
+{
+  output_isvalue_ext (test_name, (ISINF (computed) == -1), computed, parameter);
+}
+
+
+/* Tests if computed is -Inf */
+static void
+check_isinfn_exc (const char *test_name, MATHTYPE computed,
+		  int exception UNUSED)
+{
+  output_isvalue (test_name, (ISINF (computed) == -1), computed);
+}
+
+
+/****************************************************************************
+  Test for single functions of libm
+****************************************************************************/
+
+static void
+acos_test (void)
+{
+  MATHTYPE x;
+
+  check ("acos (1) == 0", FUNC(acos) (1), 0);
+
+  x = random_greater (1);
+  check_isnan_exc ("acos (x) == NaN + invalid exception for |x| > 1",
+		   FUNC(acos) (x),
+		   INVALID_EXCEPTION);
+}
+
+static void
+acosh_test (void)
+{
+  MATHTYPE x;
+
+  check ("acosh(1) == 0", FUNC(acosh) (1), 0);
+  check_isinfp ("acosh(+inf) == +inf", FUNC(acosh) (plus_infty));
+
+  x = random_less (1);
+  check_isnan_exc ("acosh(x) == NaN plus invalid exception if x < 1",
+		   FUNC(acosh) (x), INVALID_EXCEPTION);
+}
+
+
+static void
+asin_test (void)
+{
+  MATHTYPE x;
+  check ("asin (0) == 0", FUNC(asin) (0), 0);
+
+  x = random_greater (1);
+  check_isnan_exc ("asin x == NaN + invalid exception for |x| > 1",
+		   FUNC(asin) (x),
+		   INVALID_EXCEPTION);
+}
+
+static void
+asinh_test (void)
+{
+
+  check ("asinh(+0) == +0", FUNC(asinh) (0), 0);
+  check ("asinh(-0) == -0", FUNC(asinh) (minus_zero), minus_zero);
+}
+
+
+static void
+atan_test (void)
+{
+  check ("atan (0) == 0", FUNC(atan) (0), 0);
+  check ("atan (-0) == -0", FUNC(atan) (minus_zero), minus_zero);
+
+  check ("atan (+inf) == pi/2", FUNC(atan) (plus_infty), M_PI_2);
+  check ("atan (-inf) == -pi/2", FUNC(atan) (minus_infty), -M_PI_2);
+
+}
+
+static void
+atan2_test (void)
+{
+  MATHTYPE x;
+
+  x = random_greater (0);
+  check ("atan2 (0,x) == 0 for x > 0",
+	 FUNC(atan2) (0, x), 0);
+  x = random_greater (0);
+  check ("atan2 (-0,x) == -0 for x > 0",
+	 FUNC(atan2) (minus_zero, x), minus_zero);
+
+  check ("atan2 (+0,+0) == +0", FUNC(atan2) (0, 0), 0);
+  check ("atan2 (-0,+0) == -0", FUNC(atan2) (minus_zero, 0), minus_zero);
+
+  x = -random_greater (0);
+  check ("atan2 (+0,x) == +pi for x < 0", FUNC(atan2) (0, x), M_PI);
+
+  x = -random_greater (0);
+  check ("atan2 (-0,x) == -pi for x < 0", FUNC(atan2) (minus_zero, x), -M_PI);
+
+  check ("atan2 (+0,-0) == +pi", FUNC(atan2) (0, minus_zero), M_PI);
+  check ("atan2 (-0,-0) == -pi", FUNC(atan2) (minus_zero, minus_zero), -M_PI);
+
+  x = random_greater (0);
+  check ("atan2 (y,+0) == pi/2 for y > 0", FUNC(atan2) (x, 0), M_PI_2);
+
+  x = random_greater (0);
+  check ("atan2 (y,-0) == pi/2 for y > 0", FUNC(atan2) (x, minus_zero), M_PI_2);
+
+  x = random_greater (0);
+  check ("atan2 (y,-inf) == +pi for finite y > 0",
+	 FUNC(atan2) (x, minus_infty), M_PI);
+
+  x = -random_greater (0);
+  check ("atan2 (y,-inf) == -pi for finite y < 0",
+	 FUNC(atan2) (x, minus_infty), -M_PI);
+
+  check ("atan2 (+inf,+inf) == +pi/4",
+	 FUNC(atan2) (plus_infty, plus_infty), M_PI_4);
+
+  check ("atan2 (-inf,+inf) == -pi/4",
+	 FUNC(atan2) (minus_infty, plus_infty), -M_PI_4);
+
+  check ("atan2 (+inf,-inf) == +3*pi/4",
+	 FUNC(atan2) (plus_infty, minus_infty), 3 * M_PI_4);
+
+  check ("atan2 (-inf,-inf) == -3*pi/4",
+	 FUNC(atan2) (minus_infty, minus_infty), -3 * M_PI_4);
+}
+
+
+static void
+atanh_test (void)
+{
+
+  check ("atanh(+0) == +0", FUNC(atanh) (0), 0);
+  check ("atanh(-0) == -0", FUNC(atanh) (minus_zero), minus_zero);
+  check_isinfp_exc ("atanh(+1) == +inf plus divide-by-zero exception",
+		    FUNC(atanh) (1), DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfn_exc ("atanh(-1) == -inf plus divide-by-zero exception",
+		    FUNC(atanh) (-1), DIVIDE_BY_ZERO_EXCEPTION);
+}
+
+
+static void
+cbrt_test (void)
+{
+  check ("cbrt (+0) == +0", FUNC(cbrt) (0.0), 0.0);
+  check ("cbrt (-0) == -0", FUNC(cbrt) (minus_zero), minus_zero);
+
+  check ("cbrt (8) == 2", FUNC(cbrt) (8), 2);
+  check ("cbrt (-27) == -3", FUNC(cbrt) (-27.0), -3.0);
+}
+
+
+static void
+ceil_test (void)
+{
+  check ("ceil (+0) == +0", FUNC(ceil) (0.0), 0.0);
+  check ("ceil (-0) == -0", FUNC(ceil) (minus_zero), minus_zero);
+  check_isinfp ("ceil (+inf) == +inf", FUNC(ceil) (plus_infty));
+  check_isinfn ("ceil (-inf) == -inf", FUNC(ceil) (minus_infty));
+
+  check ("ceil (pi) == 4", FUNC(ceil) (M_PI), 4.0);
+  check ("ceil (-pi) == -3", FUNC(ceil) (-M_PI), 3.0);
+}
+
+
+static void
+cos_test (void)
+{
+
+  check ("cos (+0) == 1", FUNC(cos) (0), 1);
+  check ("cos (-0) == 1", FUNC(cos) (minus_zero), 1);
+  check_isnan_exc ("cos (+inf) == NaN plus invalid exception",
+		   FUNC(cos) (plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("cos (-inf) == NaN plus invalid exception",
+		   FUNC(cos) (minus_infty),
+		   INVALID_EXCEPTION);
+
+  check_eps ("cos (pi/3) == 0.5", FUNC(cos) (M_PI / 3.0),
+	     0.5, CHOOSE (0, 1e-15L, 1e-7L));
+  check_eps ("cos (pi/2) == 0.5", FUNC(cos) (M_PI_2),
+	     0, CHOOSE (1e-19L, 1e-16L, 1e-7L));
+
+}
+
+static void
+cosh_test (void)
+{
+  check ("cosh (+0) == 1", FUNC(cosh) (0), 1);
+  check ("cosh (-0) == 1", FUNC(cosh) (minus_zero), 1);
+
+  check_isinfp ("cosh (+inf) == +inf", FUNC(cosh) (plus_infty));
+  check_isinfp ("cosh (-inf) == +inf", FUNC(cosh) (minus_infty));
+}
+
+
+static void
+exp_test (void)
+{
+  check ("exp (+0) == 1", FUNC(exp) (0), 1);
+  check ("exp (-0) == 1", FUNC(exp) (minus_zero), 1);
+
+  check_isinfp ("exp (+inf) == +inf", FUNC(exp) (plus_infty));
+  check ("exp (-inf) == 0", FUNC(exp) (minus_infty), 0);
+
+  check ("exp (1) == e", FUNC(exp) (1), M_E);
+}
+
+
+#ifdef ISO_9X_IMPLEMENTED
+static void
+exp2_test (void)
+{
+  check ("exp2 (+0) == 1", FUNC(exp2) (0), 1);
+  check ("exp2 (-0) == 1", FUNC(exp2) (minus_zero), 1);
+
+  check_isinfp ("exp2 (+inf) == +inf", FUNC(exp2) (plus_infty));
+  check ("exp2 (-inf) == 0", FUNC(exp2) (minus_infty), 0);
+  check ("exp2 (10) == 1024", FUNC(exp2) (10), 1024);
+}
+#endif
+
+
+static void
+expm1_test (void)
+{
+  check ("expm1 (+0) == 0", FUNC(expm1) (0), 0);
+  check ("expm1 (-0) == -0", FUNC(expm1) (minus_zero), minus_zero);
+
+  check_isinfp ("expm1 (+inf) == +inf", FUNC(expm1) (plus_infty));
+  check ("expm1 (-inf) == -1", FUNC(expm1) (minus_infty), -1);
+
+  check ("expm1 (1) == e-1", FUNC(expm1) (1), M_E - 1.0);
+}
+
+
+
+
+static void
+check_frexp (const char *test_name, MATHTYPE computed, MATHTYPE expected,
+	     int comp_int, int exp_int)
+{
+  MATHTYPE diff;
+  int result;
+
+  result = (check_equal (computed, expected, 0, &diff)
+	    && (comp_int == exp_int));
+
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      if (verbose > 1)
+	{
+	  printf ("Result:\n");
+	  printf (" is:         %.20" PRINTF_EXPR " *2^%d\n", computed, comp_int);
+	  printf (" should be:  %.20" PRINTF_EXPR " *2^%d\n", expected, exp_int);
+	  printf (" difference: %.20" PRINTF_EXPR "\n", diff);
+	}
+      noErrors++;
+    }
+  fpstack_test (test_name);
+  output_result (test_name, result,
+		 computed, expected, diff, PRINT, PRINT);
+}
+
+
+static void
+frexp_test (void)
+{
+  int x_int;
+  MATHTYPE result;
+
+  result = FUNC(frexp) (plus_infty, &x_int);
+  check_isinfp ("frexp (+inf, expr) == +inf", result);
+
+  result = FUNC(frexp) (minus_infty, &x_int);
+  check_isinfn ("frexp (-inf, expr) == -inf", result);
+
+  result = FUNC(frexp) (nan_value, &x_int);
+  check_isnan ("frexp (Nan, expr) == NaN", result);
+
+  result = FUNC(frexp) (0, &x_int);
+  check_frexp ("frexp: +0 == 0 * 2^0", result, 0, x_int, 0);
+
+  result = FUNC(frexp) (minus_zero, &x_int);
+  check_frexp ("frexp: -0 == -0 * 2^0", result, minus_zero, x_int, 0);
+
+  result = FUNC(frexp) (12.8L, &x_int);
+  check_frexp ("frexp: 12.8 == 0.8 * 2^4", result, 0.8L, x_int, 4);
+
+  result = FUNC(frexp) (-27.34L, &x_int);
+  check_frexp ("frexp: -27.34 == -0.854375 * 2^5", result, -0.854375L, x_int, 5);
+
+}
+
+
+#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)
+/* All floating-point numbers can be put in one of these categories.  */
+enum
+{
+  FP_NAN,
+#define FP_NAN FP_NAN
+  FP_INFINITE,
+#define FP_INFINITE FP_INFINITE
+  FP_ZERO,
+#define FP_ZERO FP_ZERO
+  FP_SUBNORMAL,
+#define FP_SUBNORMAL FP_SUBNORMAL
+  FP_NORMAL
+#define FP_NORMAL FP_NORMAL
+};
+#endif
+
+
+static void
+fpclassify_test (void)
+{
+  MATHTYPE x;
+
+  /* fpclassify is a macro, don't give it constants as parameter */
+  check_bool ("fpclassify (NaN) == FP_NAN", fpclassify (nan_value) == FP_NAN);
+  check_bool ("fpclassify (+inf) == FP_INFINITE",
+	      fpclassify (plus_infty) == FP_INFINITE);
+  check_bool ("fpclassify (-inf) == FP_INFINITE",
+	      fpclassify (minus_infty) == FP_INFINITE);
+  check_bool ("fpclassify (+0) == FP_ZERO",
+	      fpclassify (plus_zero) == FP_ZERO);
+  check_bool ("fpclassify (-0) == FP_ZERO",
+	      fpclassify (minus_zero) == FP_ZERO);
+
+  x = 1000.0;
+  check_bool ("fpclassify (1000) == FP_NORMAL",
+	      fpclassify (x) == FP_NORMAL);
+}
+
+
+static void
+ldexp_test (void)
+{
+  check ("ldexp (0, 0) == 0", FUNC(ldexp) (0, 0), 0);
+
+  check_isinfp ("ldexp (+inf, 1) == +inf", FUNC(ldexp) (plus_infty, 1));
+  check_isinfn ("ldexp (-inf, 1) == -inf", FUNC(ldexp) (minus_infty, 1));
+  check_isnan ("ldexp (NaN, 1) == NaN", FUNC(ldexp) (nan_value, 1));
+
+  check ("ldexp (0.8, 4) == 12.8", FUNC(ldexp) (0.8L, 4), 12.8L);
+  check ("ldexp (-0.854375, 5) == -27.34", FUNC(ldexp) (-0.854375L, 5), -27.34L);
+}
+
+
+static void
+log_test (void)
+{
+  check_isinfn_exc ("log (+0) == -inf", FUNC(log) (0),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfn_exc ("log (-0) == -inf", FUNC(log) (minus_zero),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+
+  check ("log (1) == 0", FUNC(log) (1), 0);
+
+  check_isnan_exc ("log (x) == NaN plus divide-by-zero exception if x < 0",
+		   FUNC(log) (-1), INVALID_EXCEPTION);
+  check_isinfp ("log (+inf) == +inf", FUNC(log) (plus_infty));
+
+  check_eps ("log (e) == 1", FUNC(log) (M_E), 1, CHOOSE (0, 0, 9e-8L));
+  check ("log (1/e) == -1", FUNC(log) (1.0 / M_E), 1);
+  check ("log (2) == M_LN2", FUNC(log) (2), M_LN2);
+  check ("log (10) == M_LN10", FUNC(log) (10), M_LN10);
+}
+
+
+static void
+log10_test (void)
+{
+  check_isinfn_exc ("log10 (+0) == -inf", FUNC(log10) (0),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfn_exc ("log10 (-0) == -inf", FUNC(log10) (minus_zero),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+
+  check ("log10 (1) == +0", FUNC(log10) (1), 0);
+
+  check_isnan_exc ("log10 (x) == NaN plus divide-by-zero exception if x < 0",
+		   FUNC(log10) (-1), INVALID_EXCEPTION);
+
+  check_isinfp ("log10 (+inf) == +inf", FUNC(log10) (plus_infty));
+
+  check ("log10 (0.1) == -1", FUNC(log10) (0.1L), -1);
+  check ("log10 (10) == 1", FUNC(log10) (10.0), 1);
+  check ("log10 (100) == 2", FUNC(log10) (100.0), 2);
+  check ("log10 (10000) == 4", FUNC(log10) (10000.0), 4);
+  check_eps ("log10 (e) == M_LOG10E", FUNC(log10) (M_E), M_LOG10E,
+	     CHOOSE (0, 0, 9e-8));
+}
+
+
+static void
+log1p_test (void)
+{
+  check ("log1p (+0) == +0", FUNC(log1p) (0), 0);
+  check ("log1p (-0) == -0", FUNC(log1p) (minus_zero), minus_zero);
+
+  check_isinfn_exc ("log1p (-1) == -inf", FUNC(log1p) (-1),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isnan_exc ("log1p (x) == NaN plus divide-by-zero exception if x < -1",
+		   FUNC(log1p) (-2), INVALID_EXCEPTION);
+
+  check_isinfp ("log1p (+inf) == +inf", FUNC(log1p) (plus_infty));
+
+  check ("log1p (e-1) == 1", FUNC(log1p) (M_E - 1.0), 1);
+
+}
+
+
+#ifdef ISO_9X_IMPLEMENTED
+static void
+log2_test (void)
+{
+  check_isinfn_exc ("log2 (+0) == -inf", FUNC(log2) (0),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfn_exc ("log2 (-0) == -inf", FUNC(log2) (minus_zero),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+
+  check ("log2 (1) == +0", FUNC(log2) (1), 0);
+
+  check_isnan_exc ("log2 (x) == NaN plus divide-by-zero exception if x < 0",
+		   FUNC(log2) (-1), INVALID_EXCEPTION);
+
+  check_isinfp ("log2 (+inf) == +inf", FUNC(log2) (plus_infty));
+
+  check ("log2 (e) == M_LOG2E", FUNC(log2) (M_E), M_LOG2E);
+  check ("log2 (2) == 1", FUNC(log2) (2.0), 1);
+  check ("log2 (16) == 4", FUNC(log2) (16.0), 4);
+  check ("log2 (256) == 8", FUNC(log2) (256.0), 8);
+
+}
+#endif
+
+
+static void
+logb_test (void)
+{
+  check_isinfp ("logb (+inf) == +inf", FUNC(logb) (plus_infty));
+  check_isinfp ("logb (-inf) == +inf", FUNC(logb) (minus_infty));
+
+  check_isinfn_exc ("logb (+0) == -inf plus divide-by-zero exception",
+		    FUNC(logb) (0), DIVIDE_BY_ZERO_EXCEPTION);
+
+  check_isinfn_exc ("logb (-0) == -inf plus divide-by-zero exception",
+		    FUNC(logb) (minus_zero), DIVIDE_BY_ZERO_EXCEPTION);
+
+  check ("logb (1) == 0", FUNC(logb) (1), 0);
+  check ("logb (e) == 1", FUNC(logb) (M_E), 1);
+  check ("logb (1024) == 10", FUNC(logb) (1024), 10);
+  check ("logb (-2000) == 10", FUNC(logb) (-2000), 10);
+
+}
+
+
+static void
+sin_test (void)
+{
+  check ("sin (+0) == +0", FUNC(sin) (0), 0);
+  check ("sin (-0) == -0", FUNC(sin) (minus_zero), minus_zero);
+  check_isnan_exc ("sin (+inf) == NaN plus invalid exception",
+		   FUNC(sin) (plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("sin (-inf) == NaN plus invalid exception",
+		   FUNC(sin) (minus_infty),
+		   INVALID_EXCEPTION);
+
+  check ("sin (pi/6) == 0.5", FUNC(sin) (M_PI / 6.0), 0.5);
+  check ("sin (pi/2) == 1", FUNC(sin) (M_PI_2), 1);
+}
+
+
+static void
+sinh_test (void)
+{
+  check ("sinh (+0) == +0", FUNC(sinh) (0), 0);
+  check ("sinh (-0) == -0", FUNC(sinh) (minus_zero), minus_zero);
+
+  check_isinfp ("sinh (+inf) == +inf", FUNC(sinh) (plus_infty));
+  check_isinfn ("sinh (-inf) == -inf", FUNC(sinh) (minus_infty));
+}
+
+
+static void
+tan_test (void)
+{
+  check ("tan (+0) == -0", FUNC(tan) (0), 0);
+  check ("tan (-0) == -0", FUNC(tan) (minus_zero), minus_zero);
+  check_isnan_exc ("tan (+inf) == NaN plus invalid exception",
+		   FUNC(tan) (plus_infty), INVALID_EXCEPTION);
+  check_isnan_exc ("tan (-inf) == NaN plus invalid exception",
+		   FUNC(tan) (minus_infty), INVALID_EXCEPTION);
+
+  check_eps ("tan (pi/4) == 1", FUNC(tan) (M_PI_4), 1, CHOOSE (0, 1e-15L, 0));
+}
+
+
+static void
+tanh_test (void)
+{
+  check ("tanh (+0) == +0", FUNC(tanh) (0), 0);
+  check ("tanh (-0) == -0", FUNC(tanh) (minus_zero), minus_zero);
+
+  check ("tanh (+inf) == +1", FUNC(tanh) (plus_infty), 1);
+  check ("tanh (-inf) == -1", FUNC(tanh) (minus_infty), -1);
+}
+
+
+static void
+fabs_test (void)
+{
+  check ("fabs (+0) == +0", FUNC(fabs) (0), 0);
+  check ("fabs (-0) == +0", FUNC(fabs) (minus_zero), 0);
+
+  check_isinfp ("fabs (+inf) == +inf", FUNC(fabs) (plus_infty));
+  check_isinfp ("fabs (-inf) == +inf", FUNC(fabs) (minus_infty));
+
+  check ("fabs (+38) == 38", FUNC(fabs) (38.0), 38.0);
+  check ("fabs (-e) == e", FUNC(fabs) (-M_E), M_E);
+}
+
+
+static void
+floor_test (void)
+{
+  check ("floor (+0) == +0", FUNC(floor) (0.0), 0.0);
+  check ("floor (-0) == -0", FUNC(floor) (minus_zero), minus_zero);
+  check_isinfp ("floor (+inf) == +inf", FUNC(floor) (plus_infty));
+  check_isinfn ("floor (-inf) == -inf", FUNC(floor) (minus_infty));
+
+  check ("floor (pi) == 3", FUNC(floor) (M_PI), 3.0);
+  check ("floor (-pi) == -4", FUNC(floor) (-M_PI), 4.0);
+}
+
+
+static void
+hypot_report (const char *test_name, MATHTYPE computed, MATHTYPE expected)
+{
+  MATHTYPE diff;
+  int result;
+
+  result = check_equal (computed, expected, 0, &diff);
+
+  if (result)
+    {
+      if (verbose > 2)
+	printf ("Pass: %s\n", test_name);
+    }
+  else
+    {
+      if (verbose)
+	printf ("Fail: %s\n", test_name);
+      if (verbose > 1)
+	{
+	  printf ("Result:\n");
+	  printf (" is:         %.20" PRINTF_EXPR, computed);
+	  printf (" should be:  %.20" PRINTF_EXPR, expected);
+	  printf (" difference: %.20" PRINTF_EXPR "\n", diff);
+	}
+      noErrors++;
+    }
+  fpstack_test (test_name);
+  output_result (test_name, result,
+		 computed, expected, diff, PRINT, PRINT);
+}
+
+
+static void
+hypot_test (void)
+{
+  MATHTYPE a = FUNC(hypot) (12.4L, 0.7L);
+
+  hypot_report ("hypot (x,y) == hypot (y,x)", FUNC(hypot) (0.7L, 12.4L), a);
+  hypot_report ("hypot (x,y) == hypot (-x,y)", FUNC(hypot) (-12.4L, 0.7L), a);
+  hypot_report ("hypot (x,y) == hypot (-y,x)", FUNC(hypot) (-0.7L, 12.4L), a);
+  hypot_report ("hypot (x,y) == hypot (-x,-y)", FUNC(hypot) (-12.4L, -0.7L), a);
+  hypot_report ("hypot (x,y) == hypot (-y,-x)", FUNC(hypot) (-0.7L, -12.4L), a);
+  check ("hypot (x,0) == fabs (x)", FUNC(hypot) (-0.7L, 0), 0.7L);
+  check ("hypot (x,0) == fabs (x)", FUNC(hypot) (0.7L, 0), 0.7L);
+  check ("hypot (x,0) == fabs (x)", FUNC(hypot) (-1.0L, 0), 1.0L);
+  check ("hypot (x,0) == fabs (x)", FUNC(hypot) (-1.0L, 0), 1.0L);
+  check ("hypot (x,0) == fabs (x)", FUNC(hypot) (-5.7e7L, 0), 5.7e7L);
+  check ("hypot (x,0) == fabs (x)", FUNC(hypot) (-5.7e7L, 0), 5.7e7L);
+}
+
+
+static void
+pow_test (void)
+{
+  MATHTYPE x;
+
+  check ("pow (+0, +0) == 1", FUNC(pow) (0, 0), 1);
+  check ("pow (+0, -0) == 1", FUNC(pow) (0, minus_zero), 1);
+  check ("pow (-0, +0) == 1", FUNC(pow) (minus_zero, 0), 1);
+  check ("pow (-0, -0) == 1", FUNC(pow) (minus_zero, minus_zero), 1);
+
+  check ("pow (+10, +0) == 1", FUNC(pow) (10, 0), 1);
+  check ("pow (+10, -0) == 1", FUNC(pow) (10, minus_zero), 1);
+  check ("pow (-10, +0) == 1", FUNC(pow) (-10, 0), 1);
+  check ("pow (-10, -0) == 1", FUNC(pow) (-10, minus_zero), 1);
+
+  check ("pow (NaN, +0) == 1", FUNC(pow) (nan_value, 0), 1);
+  check ("pow (NaN, -0) == 1", FUNC(pow) (nan_value, minus_zero), 1);
+
+  check_isinfp ("pow (+1.1, +inf) == +inf", FUNC(pow) (1.1, plus_infty));
+  check_isinfp ("pow (+inf, +inf) == +inf", FUNC(pow) (plus_infty, plus_infty));
+  check_isinfp ("pow (-1.1, +inf) == +inf", FUNC(pow) (-1.1, plus_infty));
+  check_isinfp ("pow (-inf, +inf) == +inf", FUNC(pow) (minus_infty, plus_infty));
+
+  check ("pow (0.9, +inf) == +0", FUNC(pow) (0.9L, plus_infty), 0);
+  check ("pow (1e-7, +inf) == +0", FUNC(pow) (1e-7L, plus_infty), 0);
+  check ("pow (-0.9, +inf) == +0", FUNC(pow) (-0.9L, plus_infty), 0);
+  check ("pow (-1e-7, +inf) == +0", FUNC(pow) (-1e-7L, plus_infty), 0);
+
+  check ("pow (+1.1, -inf) == +inf", FUNC(pow) (1.1, minus_infty), 0);
+  check ("pow (+inf, -inf) == +inf", FUNC(pow) (plus_infty, minus_infty), 0);
+  check ("pow (-1.1, -inf) == +inf", FUNC(pow) (-1.1, minus_infty), 0);
+  check ("pow (-inf, -inf) == +inf", FUNC(pow) (minus_infty, minus_infty), 0);
+
+  check_isinfp ("pow (0.9, -inf) == +0", FUNC(pow) (0.9L, minus_infty));
+  check_isinfp ("pow (1e-7, -inf) == +0", FUNC(pow) (1e-7L, minus_infty));
+  check_isinfp ("pow (-0.9, -inf) == +0", FUNC(pow) (-0.9L, minus_infty));
+  check_isinfp ("pow (-1e-7, -inf) == +0", FUNC(pow) (-1e-7L, minus_infty));
+
+  check_isinfp ("pow (+inf, 1e-7) == +inf", FUNC(pow) (plus_infty, 1e-7L));
+  check_isinfp ("pow (+inf, 1) == +inf", FUNC(pow) (plus_infty, 1));
+  check_isinfp ("pow (+inf, 1e7) == +inf", FUNC(pow) (plus_infty, 1e7L));
+
+  check ("pow (+inf, -1e-7) == 0", FUNC(pow) (plus_infty, -1e-7L), 0);
+  check ("pow (+inf, -1) == 0", FUNC(pow) (plus_infty, -1), 0);
+  check ("pow (+inf, -1e7) == 0", FUNC(pow) (plus_infty, -1e7L), 0);
+
+  check_isinfn ("pow (-inf, 1) == -inf", FUNC(pow) (minus_infty, 1));
+  check_isinfn ("pow (-inf, 11) == -inf", FUNC(pow) (minus_infty, 11));
+  check_isinfn ("pow (-inf, 1001) == -inf", FUNC(pow) (minus_infty, 1001));
+
+  check_isinfp ("pow (-inf, 2) == +inf", FUNC(pow) (minus_infty, 2));
+  check_isinfp ("pow (-inf, 12) == +inf", FUNC(pow) (minus_infty, 12));
+  check_isinfp ("pow (-inf, 1002) == +inf", FUNC(pow) (minus_infty, 1002));
+  check_isinfp ("pow (-inf, 0.1) == +inf", FUNC(pow) (minus_infty, 0.1));
+  check_isinfp ("pow (-inf, 1.1) == +inf", FUNC(pow) (minus_infty, 1.1));
+  check_isinfp ("pow (-inf, 11.1) == +inf", FUNC(pow) (minus_infty, 11.1));
+  check_isinfp ("pow (-inf, 1001.1) == +inf", FUNC(pow) (minus_infty, 1001.1));
+
+  check ("pow (-inf, -1) == -0", FUNC(pow) (-minus_infty, -1), minus_zero);
+  check ("pow (-inf, -11) == -0", FUNC(pow) (-minus_infty, -11), minus_zero);
+  check ("pow (-inf, -1001) == -0", FUNC(pow) (-minus_infty, -1001), minus_zero);
+
+  check ("pow (-inf, -2) == +0", FUNC(pow) (minus_infty, -2), 0);
+  check ("pow (-inf, -12) == +0", FUNC(pow) (minus_infty, -12), 0);
+  check ("pow (-inf, -1002) == +0", FUNC(pow) (minus_infty, -1002), 0);
+  check ("pow (-inf, -0.1) == +0", FUNC(pow) (minus_infty, -0.1), 0);
+  check ("pow (-inf, -1.1) == +0", FUNC(pow) (minus_infty, -1.1), 0);
+  check ("pow (-inf, -11.1) == +0", FUNC(pow) (minus_infty, -11.1), 0);
+  check ("pow (-inf, -1001.1) == +0", FUNC(pow) (minus_infty, -1001.1), 0);
+
+  check_isnan ("pow (NaN, NaN) == NaN", FUNC(pow) (nan_value, nan_value));
+  check_isnan ("pow (0, NaN) == NaN", FUNC(pow) (0, nan_value));
+  check_isnan ("pow (1, NaN) == NaN", FUNC(pow) (1, nan_value));
+  check_isnan ("pow (-1, NaN) == NaN", FUNC(pow) (-1, nan_value));
+  check_isnan ("pow (NaN, 1) == NaN", FUNC(pow) (nan_value, 1));
+  check_isnan ("pow (NaN, -1) == NaN", FUNC(pow) (nan_value, -1));
+
+  x = random_greater (0.0);
+  check_isnan_ext ("pow (x, NaN) == NaN", FUNC(pow) (x, nan_value), x);
+
+  check_isnan_exc ("pow (+1, +inf) == NaN", FUNC(pow) (1, plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("pow (-1, +inf) == NaN", FUNC(pow) (1, plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("pow (+1, -inf) == NaN", FUNC(pow) (1, plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("pow (-1, -inf) == NaN", FUNC(pow) (1, plus_infty),
+		   INVALID_EXCEPTION);
+
+  check_isnan_exc ("pow (-0.1, 1.1) == NaN", FUNC(pow) (-0.1, 1.1),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("pow (-0.1, -1.1) == NaN", FUNC(pow) (-0.1, -1.1),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("pow (-10.1, 1.1) == NaN", FUNC(pow) (-10.1, 1.1),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("pow (-10.1, -1.1) == NaN", FUNC(pow) (-10.1, -1.1),
+		   INVALID_EXCEPTION);
+
+  check_isinfp_exc ("pow (+0, -1) == +inf", FUNC(pow) (0, -1),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfp_exc ("pow (+0, -11) == +inf", FUNC(pow) (0, -11),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfn_exc ("pow (-0, -1) == -inf", FUNC(pow) (minus_zero, -1),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfn_exc ("pow (-0, -11) == -inf", FUNC(pow) (minus_zero, -11),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+
+  check_isinfp_exc ("pow (+0, -2) == +inf", FUNC(pow) (0, -2),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfp_exc ("pow (+0, -11.1) == +inf", FUNC(pow) (0, -11.1),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfp_exc ("pow (-0, -2) == +inf", FUNC(pow) (minus_zero, -2),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfp_exc ("pow (-0, -11.1) == +inf", FUNC(pow) (minus_zero, -11.1),
+		    DIVIDE_BY_ZERO_EXCEPTION);
+
+  check ("pow (+0, 1) == +0", FUNC(pow) (0, 1), 0);
+  check ("pow (+0, 11) == +0", FUNC(pow) (0, 11), 0);
+  check ("pow (-0, 1) == -0", FUNC(pow) (minus_zero, 1), minus_zero);
+  check ("pow (-0, 11) == -0", FUNC(pow) (minus_zero, 11), minus_zero);
+
+  check ("pow (+0, 2) == +0", FUNC(pow) (0, 2), 0);
+  check ("pow (+0, 11.1) == +0", FUNC(pow) (0, 11.1), 0);
+  check ("pow (-0, 2) == +0", FUNC(pow) (minus_zero, 2), 0);
+  check ("pow (-0, 11.1) == +0", FUNC(pow) (minus_zero, 11.1), 0);
+
+  x = random_greater (0.0);
+  check_isinfp_ext ("pow (x, +inf) == +inf for |x| > 1",
+		    FUNC(pow) (x, plus_infty), x);
+
+  x = random_value (-1.0, 1.0);
+  check_ext ("pow (x, +inf) == +0 for |x| < 1",
+	     FUNC(pow) (x, plus_infty), 0.0, x);
+
+  x = random_greater (0.0);
+  check_ext ("pow (x, -inf) == +0 for |x| > 1",
+	     FUNC(pow) (x, minus_infty), 0.0, x);
+
+  x = random_value (-1.0, 1.0);
+  check_isinfp_ext ("pow (x, -inf) == +inf for |x| < 1",
+		    FUNC(pow) (x, minus_infty), x);
+
+  x = random_greater (0.0);
+  check_isinfp_ext ("pow (+inf, y) == +inf for y > 0",
+		    FUNC(pow) (plus_infty, x), x);
+
+  x = random_less (0.0);
+  check_ext ("pow (+inf, y) == +0 for y < 0",
+	     FUNC(pow) (plus_infty, x), 0.0, x);
+
+  x = (rand () % 1000000) * 2.0 + 1;	/* Get random odd integer > 0 */
+  check_isinfn_ext ("pow (-inf, y) == -inf for y an odd integer > 0",
+		    FUNC(pow) (minus_infty, x), x);
+
+  x = ((rand () % 1000000) + 1) * 2.0;	/* Get random even integer > 1 */
+  check_isinfp_ext ("pow (-inf, y) == +inf for y > 0 and not an odd integer",
+		    FUNC(pow) (minus_infty, x), x);
+
+  x = -((rand () % 1000000) * 2.0 + 1);	/* Get random odd integer < 0 */
+  check_ext ("pow (-inf, y) == -0 for y an odd integer < 0",
+	     FUNC(pow) (minus_infty, x), minus_zero, x);
+
+  x = ((rand () % 1000000) + 1) * -2.0;	/* Get random even integer < 0 */
+  check_ext ("pow (-inf, y) == -0 for y < 0 and not an odd integer",
+	     FUNC(pow) (minus_infty, x), minus_zero, x);
+
+  x = (rand () % 1000000) * 2.0 + 1;	/* Get random odd integer > 0 */
+  check_ext ("pow (+0, y) == +0 for y an odd integer > 0",
+	     FUNC(pow) (0.0, x), 0.0, x);
+  x = (rand () % 1000000) * 2.0 + 1;	/* Get random odd integer > 0 */
+  check_ext ("pow (-0, y) == -0 for y an odd integer > 0",
+	     FUNC(pow) (minus_zero, x), minus_zero, x);
+
+  x = ((rand () % 1000000) + 1) * 2.0;	/* Get random even integer > 1 */
+  check_ext ("pow (+0, y) == +0 for y > 0 and not an odd integer",
+	     FUNC(pow) (0.0, x), 0.0, x);
+
+  x = ((rand () % 1000000) + 1) * 2.0;	/* Get random even integer > 1 */
+  check_ext ("pow (-0, y) == +0 for y > 0 and not an odd integer",
+	     FUNC(pow) (minus_zero, x), 0.0, x);
+}
+
+
+static void
+inverse_func_pair_test (const char *test_name,
+			mathfunc f1, mathfunc inverse,
+			MATHTYPE x, MATHTYPE epsilon)
+{
+  MATHTYPE a, b, difference;
+  int result;
+
+  a = f1 (x);
+  this_does_nothing ();
+  b = inverse (a);
+  this_does_nothing ();
+
+  result = check_equal (b, x, epsilon, &difference);
+  output_result (test_name, result,
+		 b, x, difference, PRINT, PRINT);
+}
+
+
+static void
+inverse_functions (void)
+{
+  inverse_func_pair_test ("(asin(sin(x)) == x",
+			FUNC(sin), FUNC(asin), 1.0, CHOOSE (0, 0, 1e-7L));
+  inverse_func_pair_test ("(sin(asin(x)) == x",
+			  FUNC(asin), FUNC(sin), 1.0, 0.0);
+
+  inverse_func_pair_test ("(acos(cos(x)) == x",
+		       FUNC(cos), FUNC(acos), 1.0, CHOOSE (0, 1e-15L, 0));
+  inverse_func_pair_test ("(cos(acos(x)) == x",
+			  FUNC(acos), FUNC(cos), 1.0, 0.0);
+  inverse_func_pair_test ("(atan(tan(x)) == x",
+			  FUNC(tan), FUNC(atan), 1.0, 0.0);
+  inverse_func_pair_test ("(tan(atan(x)) == x",
+		       FUNC(atan), FUNC(tan), 1.0, CHOOSE (0, 1e-15L, 0));
+
+  inverse_func_pair_test ("(asinh(sinh(x)) == x",
+		     FUNC(sinh), FUNC(asinh), 1.0, CHOOSE (1e-18L, 0, 0));
+  inverse_func_pair_test ("(sinh(asinh(x)) == x",
+			  FUNC(asinh), FUNC(sinh), 1.0, 0.0);
+
+  inverse_func_pair_test ("(acosh(cosh(x)) == x",
+		FUNC(cosh), FUNC(acosh), 1.0, CHOOSE (1e-18L, 1e-15L, 0));
+  inverse_func_pair_test ("(cosh(acosh(x)) == x",
+			  FUNC(acosh), FUNC(cosh), 1.0, 0.0);
+
+  inverse_func_pair_test ("(atanh(tanh(x)) == x",
+		     FUNC(tanh), FUNC(atanh), 1.0, CHOOSE (0, 1e-15L, 0));
+  inverse_func_pair_test ("(tanh(atanh(x)) == x",
+			  FUNC(atanh), FUNC(tanh), 1.0, 0.0);
+
+}
+
+/* Test sin and cos with the identity: sin(x)^2 + cos(x)^2 = 1.  */
+static void
+identities1_test (MATHTYPE x, MATHTYPE epsilon)
+{
+  MATHTYPE res1, res2, res3, diff;
+  int result;
+
+  res1 = FUNC(sin) (x);
+  this_does_nothing ();
+  res2 = FUNC(cos) (x);
+  this_does_nothing ();
+  res3 = res1 * res1 + res2 * res2;
+  this_does_nothing ();
+
+  result = check_equal (res3, 1.0, epsilon, &diff);
+  output_result_ext ("sin^2 + cos^2 == 1", result,
+		     res3, 1.0, diff, x, PRINT, PRINT);
+}
+
+
+/* Test sin, cos, tan with the following relation: tan = sin/cos.  */
+static void
+identities2_test (MATHTYPE x, MATHTYPE epsilon)
+{
+  MATHTYPE res1, res2, res3, res4, diff;
+  int result;
+
+  res1 = FUNC(sin) (x);
+  this_does_nothing ();
+  res2 = FUNC(cos) (x);
+  this_does_nothing ();
+  res3 = FUNC(tan) (x);
+  this_does_nothing ();
+  res4 = res1 / res2;
+  this_does_nothing ();
+
+  result = check_equal (res4, res3, epsilon, &diff);
+  output_result_ext ("sin/cos == tan", result,
+		     res4, res3, diff, x, PRINT, PRINT);
+}
+
+
+/* Test cosh and sinh with the identity cosh^2 - sinh^2 = 1.  */
+static void
+identities3_test (MATHTYPE x, MATHTYPE epsilon)
+{
+  MATHTYPE res1, res2, res3, diff;
+  int result;
+
+  res1 = FUNC(sinh) (x);
+  this_does_nothing ();
+  res2 = FUNC(cosh) (x);
+  this_does_nothing ();
+  res3 = res2 * res2 - res1 * res1;
+  this_does_nothing ();
+
+  result = check_equal (res3, 1.0, epsilon, &diff);
+  output_result_ext ("cosh^2 - sinh^2 == 1", result,
+		     res3, 1.0, diff, x, PRINT, PRINT);
+}
+
+
+static void
+identities (void)
+{
+  identities1_test (0.2L, CHOOSE (1e-19L, 0, 0));
+  identities1_test (0.9L, 0);
+  identities1_test (0, 0);
+  identities1_test (-1, CHOOSE (0, 0, 1e-7));
+
+  identities2_test (0.2L, CHOOSE (0, 1e-16, 0));
+  identities2_test (0.9L, CHOOSE (0, 1e-15, 0));
+  identities2_test (0, 0);
+  identities2_test (-1, CHOOSE (1e-18L, 1e-15, 0));
+
+  identities3_test (0.2L, CHOOSE (0, 0, 1e-7));
+  identities3_test (0.9L, CHOOSE (1e-18L, 1e-15, 1e-6));
+  identities3_test (0, CHOOSE (0, 0, 1e-6));
+  identities3_test (-1, CHOOSE (1e-18L, 0, 1e-6));
+}
+
+
+/*
+   Let's test that basic arithmetic is working
+   tests: Infinity and NaN
+ */
+static void
+basic_tests (void)
+{
+  /* variables are declared volatile to forbid some compiler
+     optimizations */
+  volatile MATHTYPE Inf_var, NaN_var, zero_var, one_var;
+  MATHTYPE x1, x2;
+
+  zero_var = 0.0;
+  one_var = 1.0;
+  NaN_var = nan_value;
+  Inf_var = one_var / zero_var;
+
+  this_does_nothing ();
+
+  check_isinfp ("isinf (1/0) == +1", Inf_var);
+  check_isinfn ("isinf (-1/0) == -1", -Inf_var);
+  check_bool ("!isinf (1)", !(FUNC(isinf) (one_var)));
+  check_bool ("!isinf (0/0)", !(FUNC(isinf) (NaN_var)));
+
+  check_isnan ("isnan (0/0)", NaN_var);
+  check_isnan ("isnan (-(0/0))", -NaN_var);
+  check_bool ("!isnan (1)", !(FUNC(isnan) (one_var)));
+  check_bool ("!isnan (0/0)", !(FUNC(isnan) (Inf_var)));
+
+  check_bool ("inf == inf", Inf_var == Inf_var);
+  check_bool ("-inf == -inf", -Inf_var == -Inf_var);
+  check_bool ("inf != -inf", Inf_var != -Inf_var);
+  check_bool ("NaN != NaN", NaN_var != NaN_var);
+
+  /*
+     the same tests but this time with NAN from <nan.h>
+     NAN is a double const
+   */
+  check_bool ("isnan (NAN)", isnan (NAN));
+  check_bool ("isnan (-NAN)", isnan (-NAN));
+  check_bool ("!isinf (NAN)", !(isinf (NAN)));
+  check_bool ("!isinf (-NAN)", !(isinf (-NAN)));
+  check_bool ("NAN != NAN", NAN != NAN);
+
+  /* test if EPSILON is ok */
+  x1 = MATHCONST (1.0);
+  x2 = x1 + CHOOSE (LDBL_EPSILON, DBL_EPSILON, FLT_EPSILON);
+  check_bool ("1 != 1+EPSILON", x1 != x2);
+
+  x1 = MATHCONST (1.0);
+  x2 = x1 - CHOOSE (LDBL_EPSILON, DBL_EPSILON, FLT_EPSILON);
+  check_bool ("1 != 1-EPSILON", x1 != x2);
+
+  /* test if HUGE_VALx is ok */
+  x1 = CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF);
+  check_bool ("isinf (HUGE_VALx) == +1", ISINF (x1) == +1);
+  x1 = -CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF);
+  check_bool ("isinf (-HUGE_VALx) == -1", ISINF (x1) == -1);
+
+}
+
+
+static void
+initialize (void)
+{
+  plus_zero = 0.0;
+  nan_value = plus_zero / plus_zero;	/* Suppress GCC warning */
+
+  minus_zero = copysign (0.0, -1.0);
+  plus_infty = CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF);
+  minus_infty = -CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF);
+
+  /* Test to make sure we start correctly.  */
+  fpstack_test ("*init*");
+}
+
+
+static struct option long_options[] =
+{
+  {"verbose", optional_argument, NULL, 'v'},
+  {"silent", no_argument, NULL, 's'},
+  {0, 0, 0, 0}
+};
+
+
+static void
+parse_options (int argc, char *argv[])
+{
+  int c;
+  int option_index;
+
+  verbose = 1;
+
+  while (1)
+    {
+      c = getopt_long (argc, argv, "vs",
+		       long_options, &option_index);
+
+      /* Detect the end of the options. */
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case 'v':
+	  if (optarg)
+	    verbose = (unsigned int) strtoul (optarg, NULL, 0);
+	  else
+	    verbose = 3;
+	  break;
+	case 's':
+	  verbose = 0;
+	default:
+	  break;
+	}
+    }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  parse_options (argc, argv);
+
+  initialize ();
+  printf (TEST_MSG);
+  basic_tests ();
+
+  acos_test ();
+  acosh_test ();
+  asin_test ();
+  asinh_test ();
+  atan_test ();
+  atanh_test ();
+  atan2_test ();
+  cbrt_test ();
+  ceil_test ();
+  cos_test ();
+  cosh_test ();
+  exp_test ();
+#ifdef ISO_9X_IMPLEMENTED
+  exp2_test ();
+#endif
+  expm1_test ();
+  frexp_test ();
+  ldexp_test ();
+  log_test ();
+  log10_test ();
+  log1p_test ();
+#ifdef ISO_9X_IMPLEMENTED
+  log2_test ();
+#endif
+  logb_test ();
+  sin_test ();
+  sinh_test ();
+  tan_test ();
+  tanh_test ();
+  fabs_test ();
+  floor_test ();
+  fpclassify_test ();
+  hypot_test ();
+  pow_test ();
+
+  identities ();
+  inverse_functions ();
+
+  if (noErrors)
+    {
+      printf ("\n%d errors occured.\n", noErrors);
+      exit (1);
+    }
+  printf ("\n All tests passed sucessfully.\n");
+  exit (0);
+}
diff --git a/math/math.h b/math/math.h
index 22274f023e..89c1cfa9bb 100644
--- a/math/math.h
+++ b/math/math.h
@@ -128,9 +128,9 @@ enum
 /* Return number of classification appropriate for X.  */
 #define fpclassify(x) \
      (sizeof (x) == sizeof (float) ?					      \
-        __finitef (x)							      \
+        __fpclassifyf (x)							      \
       : sizeof (x) == sizeof (double) ?					      \
-        __finite (x) : __finitel (x))
+        __fpclassify (x) : __fpclassifyl (x))
 
 /* Return nonzero value if sign of X is negative.  */
 #define signbit(x) \
diff --git a/nis/nss_nis/nis-ethers.c b/nis/nss_nis/nis-ethers.c
index c6656ee05f..2d08be7967 100644
--- a/nis/nss_nis/nis-ethers.c
+++ b/nis/nss_nis/nis-ethers.c
@@ -53,7 +53,7 @@ static struct response *start = NULL;
 static struct response *next = NULL;
 
 static int
-saveit (int instatus, char *inkey, int inkeylen, char *inval, 
+saveit (int instatus, char *inkey, int inkeylen, char *inval,
 	int invallen, char *indata)
 {
   if (instatus != YP_TRUE)
@@ -76,7 +76,7 @@ saveit (int instatus, char *inkey, int inkeylen, char *inval,
       strncpy (next->val, inval, invallen);
       next->val[invallen] = '\0';
     }
-  
+
   return 0;
 }
 
@@ -85,9 +85,10 @@ internal_nis_setetherent (void)
 {
   char *domainname;
   struct ypall_callback ypcb;
-  
-  yp_get_default_domain(&domainname);
-  
+  enum nss_status status;
+
+  yp_get_default_domain (&domainname);
+
   while (start != NULL)
     {
       if (start->val != NULL)
@@ -100,10 +101,10 @@ internal_nis_setetherent (void)
 
   ypcb.foreach = saveit;
   ypcb.data = NULL;
-  yp_all(domainname, "ethers.byname", &ypcb);
+  status = yperr2nss (yp_all (domainname, "ethers.byname", &ypcb));
   next = start;
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -119,7 +120,7 @@ _nss_nis_setetherent (void)
 
   return result;
 }
-  
+
 enum nss_status
 _nss_nis_endetherent (void)
 {
@@ -135,9 +136,9 @@ _nss_nis_endetherent (void)
     }
   start = NULL;
   next = NULL;
-  
+
   __libc_lock_unlock (lock);
-  
+
   return NSS_STATUS_SUCCESS;
 }
 
@@ -154,15 +155,15 @@ internal_nis_getetherent_r (struct ether *eth, char *buffer, size_t buflen)
   do
     {
       char *p;
-      
+
       if (next == NULL)
 	return NSS_STATUS_NOTFOUND;
       p = strcpy (buffer, next->val);
       next = next->next;
-      
+
       while (isspace (*p))
         ++p;
-      
+
       parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
       if (!parse_res && errno == ERANGE)
         return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index bab7f4c5f4..42fc5aeac7 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
 
@@ -242,7 +242,7 @@ _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
 }
 
 enum nss_status
-_nss_nis_gethostbyname_r (const char *name, struct hostent *host,
+_nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
 			  char *buffer, size_t buflen, int *h_errnop)
 {
   enum nss_status retval;
@@ -297,9 +297,9 @@ _nss_nis_gethostbyname_r (const char *name, struct hostent *host,
 
   parse_res = parse_line (p, host, data, buflen);
 
-  if (!parse_res)
+  if (!parse_res || host->h_addrtype != af)
     {
-      if (errno == ERANGE)
+      if (!parse_res && errno == ERANGE)
 	{
 	  *h_errnop = NETDB_INTERNAL;
 	  return NSS_STATUS_TRYAGAIN;
@@ -316,6 +316,24 @@ _nss_nis_gethostbyname_r (const char *name, struct hostent *host,
 }
 
 enum nss_status
+_nss_nis_gethostbyname_r (const char *name, struct hostent *host,
+			  char *buffer, size_t buflen, int *h_errnop)
+{
+  if (_res.options & RES_USE_INET6)
+    {
+      enum nss_status status;
+
+      status = _nss_nis_gethostbyname2_r (name, AF_INET6, host, buffer, buflen,
+					  h_errnop);
+      if (status == NSS_STATUS_SUCCESS)
+	return status;
+    }
+
+  return _nss_nis_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
+				    h_errnop);
+}
+
+enum nss_status
 _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
 			  struct hostent *host, char *buffer, size_t buflen,
 			  int *h_errnop)
diff --git a/nis/nss_nis/nis-proto.c b/nis/nss_nis/nis-proto.c
index 3349fe5b36..92ef1c0010 100644
--- a/nis/nss_nis/nis-proto.c
+++ b/nis/nss_nis/nis-proto.c
@@ -77,6 +77,7 @@ internal_nis_setprotoent (void)
 {
   char *domainname;
   struct ypall_callback ypcb;
+  enum nss_status status;
   
   yp_get_default_domain (&domainname);
   
@@ -92,10 +93,10 @@ internal_nis_setprotoent (void)
   
   ypcb.foreach = saveit;
   ypcb.data = NULL;
-  yp_all (domainname, "protocols.bynumber", &ypcb);
+  status = yperr2nss (yp_all (domainname, "protocols.bynumber", &ypcb));
   next = start;
   
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
diff --git a/nis/nss_nis/nis-rpc.c b/nis/nss_nis/nis-rpc.c
index c0e21d83da..c4c9135e3f 100644
--- a/nis/nss_nis/nis-rpc.c
+++ b/nis/nss_nis/nis-rpc.c
@@ -85,6 +85,7 @@ internal_nis_setrpcent (intern_t *intern)
 {
   char *domainname;
   struct ypall_callback ypcb;
+  enum nss_status status;
   
   if (yp_get_default_domain (&domainname))
     return NSS_STATUS_UNAVAIL;
@@ -101,10 +102,10 @@ internal_nis_setrpcent (intern_t *intern)
 
   ypcb.foreach = saveit;
   ypcb.data = (char *)intern;
-  yp_all(domainname, "rpc.bynumber", &ypcb);
+  status = yperr2nss (yp_all(domainname, "rpc.bynumber", &ypcb));
   intern->next = intern->start;
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index 46c3364fe3..fe189b161b 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -50,13 +50,13 @@ struct intern_t
 };
 typedef struct intern_t intern_t;
 
-static intern_t intern = {NULL, NULL};
+static intern_t intern = { NULL, NULL };
 
 static int
-saveit (int instatus, char *inkey, int inkeylen, char *inval, 
+saveit (int instatus, char *inkey, int inkeylen, char *inval,
         int invallen, char *indata)
 {
-  intern_t *intern = (intern_t *)indata;
+  intern_t *intern = (intern_t *) indata;
 
   if (instatus != YP_TRUE)
     return instatus;
@@ -78,7 +78,7 @@ saveit (int instatus, char *inkey, int inkeylen, char *inval,
       strncpy (intern->next->val, inval, invallen);
       intern->next->val[invallen] = '\0';
     }
-  
+
   return 0;
 }
 
@@ -87,10 +87,11 @@ internal_nis_setservent (intern_t *intern)
 {
   char *domainname;
   struct ypall_callback ypcb;
-  
+  enum nss_status status;
+
   if (yp_get_default_domain (&domainname))
     return NSS_STATUS_UNAVAIL;
-  
+
   while (intern->start != NULL)
     {
       if (intern->start->val != NULL)
@@ -102,11 +103,11 @@ internal_nis_setservent (intern_t *intern)
   intern->start = NULL;
 
   ypcb.foreach = saveit;
-  ypcb.data = (char *)intern;
-  yp_all(domainname, "services.byname", &ypcb);
+  ypcb.data = (char *) intern;
+  status = yperr2nss (yp_all (domainname, "services.byname", &ypcb));
   intern->next = intern->start;
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 enum nss_status
 _nss_nis_setservent (void)
@@ -134,7 +135,7 @@ internal_nis_endservent (intern_t * intern)
       free (intern->next);
     }
   intern->start = NULL;
-  
+
   return NSS_STATUS_SUCCESS;
 }
 
@@ -161,7 +162,7 @@ internal_nis_getservent_r (struct servent *serv, char *buffer,
 
   if (data->start == NULL)
     internal_nis_setservent (data);
-  
+
   /* Get the next entry until we found a correct one. */
   do
     {
@@ -171,7 +172,7 @@ internal_nis_getservent_r (struct servent *serv, char *buffer,
       data->next = data->next->next;
       while (isspace (*p))
         ++p;
-      
+
       parse_res = _nss_files_parse_servent (p, serv, buffer, buflen);
       if (!parse_res && errno == ERANGE)
         return NSS_STATUS_TRYAGAIN;
@@ -199,7 +200,7 @@ enum nss_status
 _nss_nis_getservbyname_r (const char *name, char *protocol,
 			  struct servent *serv, char *buffer, size_t buflen)
 {
-  intern_t data = {NULL, NULL};
+  intern_t data = { NULL, NULL };
   enum nss_status status;
   int found;
 
@@ -221,16 +222,16 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
       if (strcmp (serv->s_proto, protocol) == 0)
 	{
 	  char **cp;
-	  
+
 	  if (strcmp (serv->s_name, name) == 0)
 	    found = 1;
 	  else
 	    for (cp = serv->s_aliases; *cp; cp++)
-	      if (strcmp(name, *cp) == 0)
+	      if (strcmp (name, *cp) == 0)
 		found = 1;
 	}
     }
-  
+
   internal_nis_endservent (&data);
 
   if (!found && status == NSS_STATUS_SUCCESS)
@@ -243,7 +244,7 @@ enum nss_status
 _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
 			  char *buffer, size_t buflen)
 {
-  intern_t data = {NULL, NULL};
+  intern_t data = { NULL, NULL };
   enum nss_status status;
   int found;
 
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index 6644118ac8..b128ad6366 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
 
@@ -167,7 +167,8 @@ __yp_bind (const char *domain, dom_binding ** ypdb)
                   ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
                   sizeof (ysd->dom_server_addr.sin_addr.s_addr));
           ysd->dom_vers = YPVERS;
-          strcpy (ysd->dom_domain, domain);
+          strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
+	  ysd->dom_domain[YPMAXDOMAIN] = '\0';
         }
 
       if (ysd->dom_client)
diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c
index e26d3fa03b..d6dd6daea7 100644
--- a/nss/nss_files/files-hosts.c
+++ b/nss/nss_files/files-hosts.c
@@ -98,6 +98,13 @@ DB_LOOKUP (hostbyname, ,,
 	   LOOKUP_NAME (h_name, h_aliases),
 	   const char *name)
 
+DB_LOOKUP (hostbyname2, ,,
+	   {
+	     if (result->h_addrtype != af)
+	       continue;
+	     LOOKUP_NAME (h_name, h_aliases)
+	   }, const char *name, int af)
+
 DB_LOOKUP (hostbyaddr, ,,
 	   {
 	     if (result->h_addrtype == type && result->h_length == len &&
diff --git a/posix/Makefile b/posix/Makefile
index 83509f65e6..53061c0828 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -38,7 +38,7 @@ routines :=								      \
 	execve fexecve execv execle execl execvp execlp			      \
 	getpid getppid							      \
 	getuid geteuid getgid getegid getgroups setuid setgid group_member    \
-	getpgid setpgid getpgrp setpgrp getsid setsid			      \
+	getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid	      \
 	getlogin getlogin_r setlogin					      \
 	pathconf sysconf fpathconf					      \
 	glob fnmatch regex						      \
diff --git a/posix/bsd-getpgrp.c b/posix/bsd-getpgrp.c
new file mode 100644
index 0000000000..e736e9d082
--- /dev/null
+++ b/posix/bsd-getpgrp.c
@@ -0,0 +1,30 @@
+/* BSD-compatible versions of getpgrp function.
+   Copyright (C) 1991, 92, 94, 95, 96, 97 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sys/types.h>
+
+/* Don't include unistd.h because it declares a conflicting
+   prototype for the POSIX.1 `getpgrp' function.  */
+extern pid_t __getpgid __P ((pid_t));
+
+pid_t
+__bsd_getpgrp (pid_t pid)
+{
+  return __getpgid (pid);
+}
diff --git a/posix/unistd.h b/posix/unistd.h
index 0a75224134..32edad2d12 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -183,7 +183,7 @@ extern int euidaccess __P ((__const char *__name, int __type));
 #define	SEEK_END	2	/* Seek from end of file.  */
 #endif
 
-#if defined (__USE_BSD) && !defined (L_SET)
+#if defined __USE_BSD && !defined L_SET
 /* Old BSD names for the same constants; just for compatibility.  */
 #define	L_SET		SEEK_SET
 #define	L_INCR		SEEK_CUR
@@ -239,7 +239,7 @@ extern unsigned int alarm __P ((unsigned int __seconds));
 extern unsigned int __sleep __P ((unsigned int __seconds));
 extern unsigned int sleep __P ((unsigned int __seconds));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Set an alarm to go off (generating a SIGALRM signal) in VALUE
    microseconds.  If INTERVAL is nonzero, when the alarm goes off, the
    timer is reset to go off every INTERVAL microseconds thereafter.
@@ -264,7 +264,7 @@ extern int __chown __P ((__const char *__file,
 extern int chown __P ((__const char *__file,
 		       __uid_t __owner, __gid_t __group));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Change the owner and group of the file that FD is open on.  */
 extern int __fchown __P ((int __fd,
 			  __uid_t __owner, __gid_t __group));
@@ -285,7 +285,7 @@ extern int lchown __P ((__const char *__file, __uid_t __owner,
 extern int __chdir __P ((__const char *__path));
 extern int chdir __P ((__const char *__path));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Change the process's working directory to the one FD is open on.  */
 extern int fchdir __P ((int __fd));
 #endif
@@ -317,7 +317,7 @@ char *__canonicalize_directory_name_internal __P ((__const char *__thisdir,
 						   size_t __size));
 #endif
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Put the absolute pathname of the current working directory in BUF.
    If successful, return BUF.  If not, put an error message in
    BUF and return NULL.  BUF should be at least PATH_MAX bytes long.  */
@@ -377,7 +377,7 @@ extern int execvp __P ((__const char *__file, char *__const __argv[]));
 extern int execlp __P ((__const char *__file, __const char *__arg, ...));
 
 
-#if defined(__USE_MISC) || defined(__USE_XOPEN)
+#if defined __USE_MISC || defined __USE_XOPEN
 /* Add INC to priority of the current process.  */
 extern int nice __P ((int __inc));
 #endif
@@ -420,6 +420,13 @@ extern __pid_t getppid __P ((void));
 
 /* Get the process group ID of the calling process.  */
 extern __pid_t getpgrp __P ((void));
+/* The old BSD definition is a bit different.  */
+extern __pid_t __bsd_getpgrp __P ((__pid_t __pid));
+#ifdef __FAVOR_BSD
+/* When we explicitely compile BSD sources use the BSD definition of this
+   function.  Please note that we cannot use parameters for the macro.  */
+#define getpgrp __bsd_getpgrp
+#endif
 
 /* Set the process group ID of the process matching PID to PGID.
    If PID is zero, the current process's process group ID is set.
@@ -432,7 +439,7 @@ extern __pid_t __getpgid __P ((__pid_t __pid));
 extern __pid_t getpgid __P ((__pid_t __pid));
 #endif
 
-#if defined(__USE_SVID) || defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Both System V and BSD have `setpgrp' functions, but with different
    calling conventions.  The BSD function is the same as POSIX.1 `setpgid'
    (above).  The System V function takes no arguments and puts the calling
@@ -503,7 +510,7 @@ extern int group_member __P ((__gid_t __gid));
 extern int __setuid __P ((__uid_t __uid));
 extern int setuid __P ((__uid_t __uid));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Set the real user ID of the calling process to RUID,
    and the effective user ID of the calling process to EUID.  */
 extern int __setreuid __P ((__uid_t __ruid, __uid_t __euid));
@@ -522,7 +529,7 @@ extern int seteuid __P ((__uid_t __uid));
 extern int __setgid __P ((__gid_t __gid));
 extern int setgid __P ((__gid_t __gid));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Set the real group ID of the calling process to RGID,
    and the effective group ID of the calling process to EGID.  */
 extern int __setregid __P ((__gid_t __rgid, __gid_t __egid));
@@ -541,7 +548,7 @@ extern int setegid __P ((__gid_t __gid));
 extern __pid_t __fork __P ((void));
 extern __pid_t fork __P ((void));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Clone the calling process, but without copying the whole address space.
    The the calling process is suspended until the the new process exits or is
    replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
@@ -565,7 +572,7 @@ extern int ttyname_r __P ((int __fd, char *__buf, size_t __buflen));
 extern int __isatty __P ((int __fd));
 extern int isatty __P ((int __fd));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Return the index into the active-logins file (utmp) for
    the controlling terminal.  */
 extern int ttyslot __P ((void));
@@ -576,7 +583,7 @@ extern int ttyslot __P ((void));
 extern int __link __P ((__const char *__from, __const char *__to));
 extern int link __P ((__const char *__from, __const char *__to));
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Make a symbolic link to FROM named TO.  */
 extern int __symlink __P ((__const char *__from, __const char *__to));
 extern int symlink __P ((__const char *__from, __const char *__to));
@@ -654,7 +661,7 @@ extern char *optarg;
 #endif
 
 
-#if defined(__USE_BSD) || defined (__USE_XOPEN)
+#if defined __USE_BSD || defined __USE_XOPEN
 
 /* Put the name of the current host in no more than LEN bytes of NAME.
    The result is null-terminated if LEN is large enough for the full
@@ -728,7 +735,7 @@ extern int daemon __P ((int __nochdir, int __noclose));
 #endif /* Use BSD || X/Open.  */
 
 
-#if defined(__USE_BSD) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 
 /* Return the current machine's Internet number.  */
 extern long int gethostid __P ((void));
@@ -758,7 +765,7 @@ extern int getdtablesize __P ((void));
 #endif /* Use BSD || X/Open Unix.  */
 
 
-#if defined(__USE_MISC) || defined(__USE_XOPEN_EXTENDED)
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
 
 /* Set the end of accessible data space (aka "the break") to ADDR.
    Returns zero on success and -1 for errors (with errno set).  */
@@ -793,8 +800,7 @@ extern long int syscall __P ((long int __sysno, ...));
 #endif	/* Use misc.  */
 
 
-#if (defined (__USE_MISC) || defined (__USE_XOPEN_EXTENDED)) \
-    && !defined (F_LOCK)
+#if (defined __USE_MISC || defined __USE_XOPEN_EXTENDED) && !defined F_LOCK
 /* NOTE: These declarations also appear in <fcntl.h>; be sure to keep both
    files consistent.  Some systems have them there and some here, and some
    software depends on the macros being defined without including both.  */
diff --git a/resolv/netdb.h b/resolv/netdb.h
index 41faa75e36..a0a682fe06 100644
--- a/resolv/netdb.h
+++ b/resolv/netdb.h
@@ -413,6 +413,16 @@ extern int getaddrinfo __P ((__const char *__name, __const char *__service,
 
 /* Free `addrinfo' structure AI including associated storage.  */
 extern void freeaddrinfo __P ((struct addrinfo *__ai));
+
+/* Convert error return from getaddrinfo() to a string.  */
+extern char *gai_strerror __P  ((int __ecode));
+
+/* Translate a socket address to a location and service name.  */
+extern int getnameinfo __P ((__const struct sockaddr *__sa, size_t __salen,
+			     char *__host, size_t __hostlen,
+			     char *__serv, size_t __servlen,
+			     int __flags));
+
 #endif	/* POSIX */
 
 __END_DECLS
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
index ac939ec4b4..e2e64695d5 100644
--- a/stdio-common/printf_fphex.c
+++ b/stdio-common/printf_fphex.c
@@ -77,6 +77,10 @@ ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
       done += len;							      \
     }									      \
   while (0)
+
+#ifndef MIN
+# define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
 
 
 int
diff --git a/stdio/stdio.h b/stdio/stdio.h
index b2d064483b..7171c094e4 100644
--- a/stdio/stdio.h
+++ b/stdio/stdio.h
@@ -111,7 +111,7 @@ typedef __io_fileno_fn cookie_fileno_function_t;
 #endif
 
 /* Low level interface, independent of FILE representation.  */
-#if defined (__USE_GNU) && !defined (_LIBC)
+#if defined __USE_GNU && !defined _LIBC
 /* Define the user-visible type, with user-friendly member names.  */
 typedef struct
 {
@@ -340,7 +340,7 @@ extern int fcloseall __P ((void));
 extern FILE *fopen __P ((__const char *__filename, __const char *__modes));
 /* Open a file, replacing an existing stream with it. */
 extern FILE *freopen __P ((__const char *__restrict __filename,
-			   __const char *__rstrict __modes,
+			   __const char *__restrict __modes,
 			   FILE *__restrict __stream));
 
 /* Return a new, zeroed, stream.
@@ -554,7 +554,7 @@ putchar (int __c)
 #endif
 
 
-#if defined(__USE_SVID) || defined(__USE_MISC)
+#if defined __USE_SVID || defined __USE_MISC
 /* Get a word (int) from STREAM.  */
 extern int getw __P ((FILE *__stream));
 
@@ -663,8 +663,8 @@ extern int fileno __P ((FILE *__stream));
 #endif /* Use POSIX.  */
 
 
-#if (defined (__USE_POSIX2) || defined(__USE_SVID) || defined(__USE_BSD) || \
-     defined(__USE_MISC))
+#if (defined __USE_POSIX2 || defined __USE_SVID || defined __USE_BSD || \
+     defined __USE_MISC)
 /* Create a new stream connected to a pipe running the given command.  */
 extern FILE *popen __P ((__const char *__command, __const char *__modes));
 
diff --git a/stdio/vasprintf.c b/stdio/vasprintf.c
index 57bacdbb17..47a074e6ca 100644
--- a/stdio/vasprintf.c
+++ b/stdio/vasprintf.c
@@ -56,10 +56,9 @@ enlarge_buffer (stream, c)
 /* Write formatted output from FORMAT to a string which is
    allocated with malloc and stored in *STRING_PTR.  */
 int
-vasprintf (string_ptr, format, args)
-     char **string_ptr;
-     const char *format;
-     va_list args;
+vasprintf (char **string_ptr,
+	   const char *format,
+	   va_list args)
 {
   FILE f;
   int done;
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index 316adec5ff..5d892b94cb 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -113,10 +113,10 @@ static const mp_limb_t _tens_in_limb[MAX_DIG_PER_LIMB + 1] =
      1000000,             10000000,             100000000,
      1000000000
 #if BITS_PER_MP_LIMB > 32
-	       ,	  10000000000,          100000000000,
-     1000000000000,       10000000000000,       100000000000000,
-     1000000000000000,    10000000000000000,    100000000000000000,
-     1000000000000000000, 10000000000000000000U
+	       ,	   10000000000U,          100000000000U,
+     1000000000000U,       10000000000000U,       100000000000000U,
+     1000000000000000U,    10000000000000000U,    100000000000000000U,
+     1000000000000000000U, 10000000000000000000U
 #endif
 #if BITS_PER_MP_LIMB > 64
   #error "Need to expand tens_in_limb table to" MAX_DIG_PER_LIMB
diff --git a/string/strdup.c b/string/strdup.c
index 257f428ead..be3883f688 100644
--- a/string/strdup.c
+++ b/string/strdup.c
@@ -25,7 +25,7 @@
 # include <string.h>
 #else
 char *malloc ();
-char *strcpy ();
+char *memcpy ();
 #endif
 
 #ifndef weak_alias
diff --git a/sysdeps/generic/getpgrp.c b/sysdeps/generic/getpgrp.c
index d745b0fbf2..805fbfb808 100644
--- a/sysdeps/generic/getpgrp.c
+++ b/sysdeps/generic/getpgrp.c
@@ -1,28 +1,27 @@
-/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+/* Copyright (C) 1991, 1995, 1997 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 Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
+   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
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
-#include <ansidecl.h>
 #include <errno.h>
 #include <unistd.h>
 
 /* Get the process group ID of the calling process.  */
 int
-DEFUN_VOID(getpgrp)
+getpgrp (void)
 {
   return __getpgid (0);
 }
diff --git a/sysdeps/generic/netinet/in.h b/sysdeps/generic/netinet/in.h
index a59f584085..1f3e241869 100644
--- a/sysdeps/generic/netinet/in.h
+++ b/sysdeps/generic/netinet/in.h
@@ -22,6 +22,7 @@
 #include <features.h>
 
 #include <sys/socket.h>
+#include <sys/types.h>
 
 __BEGIN_DECLS
 
@@ -138,6 +139,34 @@ struct in_addr
 #endif
 
 
+/* IPv6 address */
+struct in6_addr
+  {
+    union
+      {
+	u_int8_t	u6_addr8[16];
+	u_int16_t	u6_addr16[8];
+	u_int32_t	u6_addr32[4];
+#if (~0UL) > 0xffffffff
+	u_int64_t	u6_addr64[2];
+#endif
+      } in6_u;
+#define s6_addr			in6_u.u6_addr8
+#define s6_addr16		in6_u.u6_addr16
+#define s6_addr32		in6_u.u6_addr32
+#define s6_addr64		in6_u.u6_addr64
+  };
+
+extern const struct in6_addr in6addr_any;        /* :: */
+extern const struct in6_addr in6addr_loopback;   /* ::1 */
+#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
+
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+
+
 /* Get the definition of the macro to define the common sockaddr members.  */
 #include <sockaddrcom.h>
 
@@ -156,6 +185,24 @@ struct sockaddr_in
 			   sizeof(struct in_addr)];
   };
 
+/* Ditto, for IPv6.  */
+struct sockaddr_in6
+  {
+    __SOCKADDR_COMMON (sin6_);
+    u_int16_t		sin6_port;      /* Transport layer port # */
+    u_int32_t		sin6_flowinfo;  /* IPv6 flow information */
+    struct in6_addr	sin6_addr;      /* IPv6 address */
+  };
+
+/* IPv6 multicast request.  */
+struct ipv6_mreq
+  {
+    /* IPv6 multicast address of group */
+    struct in6_addr ipv6mr_multiaddr;
+
+    /* local IPv6 address of interface */
+    int		ipv6mr_ifindex;
+  };
 
 /* Options for use with `getsockopt' and `setsockopt' at the IP level.
    The first word in the comment at the right is the data type used;
@@ -213,6 +260,52 @@ extern u_int16_t htons __P ((u_int16_t __hostshort));
 #define	htons(x)	(x)
 #endif
 
+/* IPV6 socket options.  */
+#define IPV6_ADDRFORM		1
+#define IPV6_RXINFO		2
+#define IPV6_RXHOPOPTS		3
+#define IPV6_RXDSTOPTS		4
+#define IPV6_RXSRCRT		5
+#define IPV6_PKTOPTIONS		6
+#define IPV6_CHECKSUM		7
+#define IPV6_HOPLIMIT		8
+
+#define IPV6_TXINFO		IPV6_RXINFO
+#define SCM_SRCINFO		IPV6_TXINFO
+#define SCM_SRCRT		IPV6_RXSRCRT
+
+#define IPV6_UNICAST_HOPS	16
+#define IPV6_MULTICAST_IF	17
+#define IPV6_MULTICAST_HOPS	18
+#define IPV6_MULTICAST_LOOP	19
+#define IPV6_ADD_MEMBERSHIP	20
+#define IPV6_DROP_MEMBERSHIP	21
+
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+        ((((u_int32_t *)(a))[0] == 0) && ((u_int32_t *)(a))[1] == 0) && \
+         (((u_int32_t *)(a))[2] == 0) && ((u_int32_t *)(a))[3] == 0))
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+        ((((u_int32_t *)(a))[0] == 0) && ((u_int32_t *)(a))[1] == 0) && \
+         (((u_int32_t *)(a))[2] == 0) && ((u_int32_t *)(a))[3] == htonl(1)))
+
+#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *)(a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+        ((((u_int32_t *)(a))[0] & htonl(0xffc00000)) == htonl(0xfe800000))
+
+#define IN6_IS_ADDR_SITELOCAL(a) \
+        ((((u_int32_t *)(a))[0] & htonl(0xffc00000)) == htonl(0xfec00000))
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+        ((((u_int32_t *)(a))[0] == 0) && (((u_int32_t *)(a))[1] == 0) && \
+         (((u_int32_t *)(a))[2] == htonl(0xffff)))
+
+#define IN6_IS_ADDR_V4COMPAT(a) \
+        ((((u_int32_t *)(a))[0] == 0) && (((u_int32_t *)(a))[1] == 0) && \
+         (((u_int32_t *)(a))[2] == 0) && (ntohl(((u_int32_t *)(a))[3]) > 1))
+
+
 __END_DECLS
 
 #endif	/* netinet/in.h */
diff --git a/sysdeps/generic/sys/mman.h b/sysdeps/generic/sys/mman.h
index bcda90f4ba..32b152e124 100644
--- a/sysdeps/generic/sys/mman.h
+++ b/sysdeps/generic/sys/mman.h
@@ -1,5 +1,5 @@
 /* Definitions for BSD-style memory management.  Generic/4.4 BSD version.
-   Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1995, 1996, 1997 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
@@ -97,8 +97,8 @@ int mprotect __P ((__caddr_t __addr, size_t __len, int __prot));
 
 /* Synchronize the region starting at ADDR and extending LEN bytes with the
    file it maps.  Filesystem operations on a file being mapped are
-   unpredictable before this is done.  */
-int msync __P ((__caddr_t __addr, size_t __len));
+   unpredictable before this is done.  Flags are from the MS_* set.  */
+int msync __P ((__caddr_t __addr, size_t __len, int flags));
 
 /* Advise the system about particular usage patterns the program follows
    for the region starting at ADDR and extending LEN bytes.  */
diff --git a/sysdeps/i386/huge_val.h b/sysdeps/i386/huge_val.h
new file mode 100644
index 0000000000..8af745f6c1
--- /dev/null
+++ b/sysdeps/i386/huge_val.h
@@ -0,0 +1,92 @@
+/* `HUGE_VAL' constants for ix86 (where it is infinity).
+   Used by <stdlib.h> and <math.h> functions for overflow.
+   Copyright (C) 1992, 1995, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef	   _HUGE_VAL_H
+#define	   _HUGE_VAL_H	1
+
+#include <features.h>
+#include <sys/cdefs.h>
+#include <endian.h>
+
+/* IEEE positive infinity (-HUGE_VAL is negative infinity).  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define	__HUGE_VAL_bytes	{ 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define	__HUGE_VAL_bytes	{ 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
+#endif
+
+#define __huge_val_t	union { unsigned char __c[8]; double __d; }
+#ifdef	__GNUC__
+#define	HUGE_VAL	(__extension__ \
+			 ((__huge_val_t) { __c: __HUGE_VAL_bytes }).__d)
+#else	/* Not GCC.  */
+static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
+#define	HUGE_VAL	(__huge_val.__d)
+#endif	/* GCC.  */
+
+
+/* ISO C 9X extensions: (float) HUGE_VALF and (long double) HUGE_VALL.  */
+
+#ifdef __USE_ISOC9X
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define	__HUGE_VALF_bytes	{ 0x7f, 0x80, 0, 0 }
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define	__HUGE_VALF_bytes	{ 0, 0, 0x80, 0x7f }
+#endif
+
+#define __huge_valf_t	union { unsigned char __c[4]; float __f; }
+#ifdef	__GNUC__
+#define	HUGE_VALF	(__extension__ \
+			 ((__huge_valf_t) { __c: __HUGE_VALF_bytes }).__f)
+#else	/* Not GCC.  */
+static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes };
+#define	HUGE_VALF	(__huge_valf.__f)
+#endif	/* GCC.  */
+
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define	__HUGE_VALL_bytes	{ 0x7f, 0xff, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define	__HUGE_VALL_bytes	{ 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7f, 0, 0 }
+#endif
+
+#define __huge_vall_t	union { unsigned char __c[12]; long double __ld; }
+#ifdef	__GNUC__
+#define	HUGE_VALL	(__extension__ \
+			 ((__huge_vall_t) { __c: __HUGE_VALL_bytes }).__ld)
+#else	/* Not GCC.  */
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+#define	HUGE_VALL	(__huge_vall.__ld)
+#endif	/* GCC.  */
+
+
+/* Expression representing positive infinity.  Here it is the same as
+   HUGE_VALF.  */
+#define INFINITY	HUGE_VALF
+
+#endif	/* __USE_ISOC9X.  */
+
+
+#endif	   /* huge_val.h */
diff --git a/sysdeps/ieee754/huge_val.h b/sysdeps/ieee754/huge_val.h
index 4f8b0a9574..ef9fa65902 100644
--- a/sysdeps/ieee754/huge_val.h
+++ b/sysdeps/ieee754/huge_val.h
@@ -65,21 +65,9 @@ static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes };
 #endif	/* GCC.  */
 
 
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define	__HUGE_VALL_bytes	{ 0x7f, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-#endif
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define	__HUGE_VALL_bytes	{ 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0x7f, 0, 0 }
-#endif
-
-#define __huge_vall_t	union { unsigned char __c[12]; long double __ld; }
-#ifdef	__GNUC__
-#define	HUGE_VALL	(__extension__ \
-			 ((__huge_vall_t) { __c: __HUGE_VALL_bytes }).__ld)
-#else	/* Not GCC.  */
-static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
-#define	HUGE_VALL	(__huge_vall.__ld)
-#endif	/* GCC.  */
+/* Generally there is no separate `long double' format and it is the
+   same as `double'.  */
+#define HUGE_VALL HUGE_VAL
 
 
 /* Expression representing positive infinity.  Here it is the same as
diff --git a/sysdeps/libm-i387/e_acos.S b/sysdeps/libm-i387/e_acos.S
index becae36d5e..b9d07b1091 100644
--- a/sysdeps/libm-i387/e_acos.S
+++ b/sysdeps/libm-i387/e_acos.S
@@ -10,12 +10,12 @@ RCSID("$NetBSD: e_acos.S,v 1.4 1995/05/08 23:44:37 jtc Exp $")
 /* acos = atan (sqrt(1 - x^2) / x) */
 ENTRY(__ieee754_acos)
 	fldl	4(%esp)			/* x */
-	fst	%st(1)
-	fmul	%st(0)			/* x^2 */
-	fld1
-	fsubp				/* 1 - x^2 */
-	fsqrt				/* sqrt (1 - x^2) */
-	fxch	%st(1)
-	fpatan
+	fld	%st			/* x : x */
+	fmul	%st(0)			/* x^2 : x */
+	fld1				/* 1 : x^2 : x */
+	fsubp				/* 1 - x^2 : x */
+	fsqrt				/* sqrt (1 - x^2) : x */
+	fxch	%st(1)			/* x : sqrt (1 - x^2) */
+	fpatan				/* atan (sqrt(1 - x^2) / x) */
 	ret
 END (__ieee754_acos)
diff --git a/sysdeps/libm-i387/e_acosf.S b/sysdeps/libm-i387/e_acosf.S
index 87ee2fb5bc..50b13fd1bd 100644
--- a/sysdeps/libm-i387/e_acosf.S
+++ b/sysdeps/libm-i387/e_acosf.S
@@ -11,7 +11,7 @@ RCSID("$NetBSD: $")
 /* acos = atan (sqrt(1 - x^2) / x) */
 ENTRY(__ieee754_acosf)
 	flds	4(%esp)			/* x */
-	fst	%st(1)
+	fld	%st
 	fmul	%st(0)			/* x^2 */
 	fld1
 	fsubp				/* 1 - x^2 */
diff --git a/sysdeps/libm-i387/e_acosl.S b/sysdeps/libm-i387/e_acosl.S
index e8f97485de..d69f056556 100644
--- a/sysdeps/libm-i387/e_acosl.S
+++ b/sysdeps/libm-i387/e_acosl.S
@@ -11,7 +11,7 @@
 /* acosl = atanl (sqrtl(1 - x^2) / x) */
 ENTRY(__ieee754_acosl)
 	fldt	4(%esp)			/* x */
-	fst	%st(1)
+	fld	%st
 	fmul	%st(0)			/* x^2 */
 	fld1
 	fsubp				/* 1 - x^2 */
diff --git a/sysdeps/libm-i387/e_asin.S b/sysdeps/libm-i387/e_asin.S
index 1202753d9b..945e308245 100644
--- a/sysdeps/libm-i387/e_asin.S
+++ b/sysdeps/libm-i387/e_asin.S
@@ -10,7 +10,7 @@ RCSID("$NetBSD: e_asin.S,v 1.4 1995/05/08 23:45:40 jtc Exp $")
 /* asin = atan (x / sqrt(1 - x^2)) */
 ENTRY(__ieee754_asin)
 	fldl	4(%esp)			/* x */
-	fst	%st(1)
+	fld	%st
 	fmul	%st(0)			/* x^2 */
 	fld1
 	fsubp				/* 1 - x^2 */
diff --git a/sysdeps/libm-i387/e_asinf.S b/sysdeps/libm-i387/e_asinf.S
index d2159bac37..d450e9a740 100644
--- a/sysdeps/libm-i387/e_asinf.S
+++ b/sysdeps/libm-i387/e_asinf.S
@@ -11,7 +11,7 @@ RCSID("$NetBSD: $")
 /* asin = atan (x / sqrt(1 - x^2)) */
 ENTRY(__ieee754_asinf)
 	flds	4(%esp)			/* x */
-	fst	%st(1)
+	fld	%st
 	fmul	%st(0)			/* x^2 */
 	fld1
 	fsubp				/* 1 - x^2 */
diff --git a/sysdeps/libm-i387/e_asinl.S b/sysdeps/libm-i387/e_asinl.S
index ab421f3189..3919fbcf58 100644
--- a/sysdeps/libm-i387/e_asinl.S
+++ b/sysdeps/libm-i387/e_asinl.S
@@ -12,7 +12,7 @@ RCSID("$NetBSD: $")
 /* asinl = atanl (x / sqrtl(1 - x^2)) */
 ENTRY(__ieee754_asinl)
 	fldt	4(%esp)			/* x */
-	fst	%st(1)
+	fld	%st
 	fmul	%st(0)			/* x^2 */
 	fld1
 	fsubp				/* 1 - x^2 */
diff --git a/sysdeps/libm-i387/e_exp.S b/sysdeps/libm-i387/e_exp.S
index e76b9c63df..4a75fa1d1c 100644
--- a/sysdeps/libm-i387/e_exp.S
+++ b/sysdeps/libm-i387/e_exp.S
@@ -22,7 +22,7 @@ ENTRY(__ieee754_exp)
 	je	1f			/* Is +-Inf, jump.  */
 	fldl2e
 	fmulp				/* x * log2(e) */
-	fstl	%st(1)
+	fld	%st
 	frndint				/* int(x * log2(e)) */
 	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
 	fxch
@@ -35,6 +35,7 @@ ENTRY(__ieee754_exp)
 
 1:	testl	$0x200, %eax		/* Test sign.  */
 	jz	2f			/* If positive, jump.  */
+	fstp	%st
 	fldz				/* Set result to 0.  */
 2:	ret
 END (__ieee754_exp)
diff --git a/sysdeps/libm-i387/e_expf.S b/sysdeps/libm-i387/e_expf.S
index 9a669cf8d4..5fd49b89fd 100644
--- a/sysdeps/libm-i387/e_expf.S
+++ b/sysdeps/libm-i387/e_expf.S
@@ -23,7 +23,7 @@ ENTRY(__ieee754_expf)
 	je	1f			/* Is +-Inf, jump.  */
 	fldl2e
 	fmulp				/* x * log2(e) */
-	fstl	%st(1)
+	fld	%st
 	frndint				/* int(x * log2(e)) */
 	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
 	fxch
@@ -36,6 +36,7 @@ ENTRY(__ieee754_expf)
 
 1:	testl	$0x200, %eax		/* Test sign.  */
 	jz	2f			/* If positive, jump.  */
+	fstp	%st
 	fldz				/* Set result to 0.  */
 2:	ret
 END (__ieee754_expf)
diff --git a/sysdeps/libm-i387/e_expl.S b/sysdeps/libm-i387/e_expl.S
index e83d30640d..2bcdf58c58 100644
--- a/sysdeps/libm-i387/e_expl.S
+++ b/sysdeps/libm-i387/e_expl.S
@@ -24,7 +24,7 @@ ENTRY(__ieee754_expl)
 	je	1f			/* Is +-Inf, jump.  */
 	fldl2e
 	fmulp				/* x * log2(e) */
-	fstl	%st(1)
+	fld	%st
 	frndint				/* int(x * log2(e)) */
 	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
 	fxch
@@ -37,6 +37,7 @@ ENTRY(__ieee754_expl)
 
 1:	testl	$0x200, %eax		/* Test sign.  */
 	jz	2f			/* If positive, jump.  */
+	fstp	%st
 	fldz				/* Set result to 0.  */
 2:	ret
 END (__ieee754_expl)
diff --git a/sysdeps/libm-i387/e_log.S b/sysdeps/libm-i387/e_log.S
index e7f567d950..c7cacdfb0a 100644
--- a/sysdeps/libm-i387/e_log.S
+++ b/sysdeps/libm-i387/e_log.S
@@ -47,8 +47,8 @@ ENTRY(__ieee754_log)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
 	fnstsw			// x-1 : x : log(2)
-	sahf
-	ja	2f
+	andb	$0x45, %ah
+	jz	2f
 	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
diff --git a/sysdeps/libm-i387/e_log10.S b/sysdeps/libm-i387/e_log10.S
index ecb691b905..2c8488c3a9 100644
--- a/sysdeps/libm-i387/e_log10.S
+++ b/sysdeps/libm-i387/e_log10.S
@@ -47,8 +47,8 @@ ENTRY(__ieee754_log10)
 	fabs			// |x-1| : x-1 : x : log10(2)
 	fcompl	MO(limit)	// x-1 : x : log10(2)
 	fnstsw			// x-1 : x : log10(2)
-	sahf
-	ja	2f
+	andb	$0x45, %ah
+	jz	2f
 	fstp	%st(1)		// x-1 : log10(2)
 	fyl2xp1			// log10(x)
 	ret
diff --git a/sysdeps/libm-i387/e_log10f.S b/sysdeps/libm-i387/e_log10f.S
index aac58d0293..2c07161085 100644
--- a/sysdeps/libm-i387/e_log10f.S
+++ b/sysdeps/libm-i387/e_log10f.S
@@ -48,8 +48,8 @@ ENTRY(__ieee754_log10f)
 	fabs			// |x-1| : x-1 : x : log10(2)
 	fcompl	MO(limit)	// x-1 : x : log10(2)
 	fnstsw			// x-1 : x : log10(2)
-	sahf
-	ja	2f
+	andb	$0x45, %ah
+	jz	2f
 	fstp	%st(1)		// x-1 : log10(2)
 	fyl2xp1			// log10(x)
 	ret
diff --git a/sysdeps/libm-i387/e_log10l.S b/sysdeps/libm-i387/e_log10l.S
index 4f51818bdd..6fe7c5a6f7 100644
--- a/sysdeps/libm-i387/e_log10l.S
+++ b/sysdeps/libm-i387/e_log10l.S
@@ -49,8 +49,8 @@ ENTRY(__ieee754_log10l)
 	fabs			// |x-1| : x-1 : x : log10(2)
 	fcompl	MO(limit)	// x-1 : x : log10(2)
 	fnstsw			// x-1 : x : log10(2)
-	sahf
-	ja	2f
+	andb	$0x45, %ah
+	jz	2f
 	fstp	%st(1)		// x-1 : log10(2)
 	fyl2xp1			// log10(x)
 	ret
diff --git a/sysdeps/libm-i387/e_logf.S b/sysdeps/libm-i387/e_logf.S
index 4459b7fc08..bdba1d3225 100644
--- a/sysdeps/libm-i387/e_logf.S
+++ b/sysdeps/libm-i387/e_logf.S
@@ -48,8 +48,8 @@ ENTRY(__ieee754_logf)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
 	fnstsw			// x-1 : x : log(2)
-	sahf
-	ja	2f
+	andb	$0x45, %ah
+	jz	2f
 	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
diff --git a/sysdeps/libm-i387/e_logl.S b/sysdeps/libm-i387/e_logl.S
index 08447a27e7..bda3ea508e 100644
--- a/sysdeps/libm-i387/e_logl.S
+++ b/sysdeps/libm-i387/e_logl.S
@@ -48,8 +48,8 @@ ENTRY(__ieee754_logl)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
 	fnstsw			// x-1 : x : log(2)
-	sahf
-	ja	2f
+	andb	$0x45, %ah
+	jz	2f
 	fstp	%st(1)		// x-1 : log(2)
 	fyl2xp1			// log(x)
 	ret
diff --git a/sysdeps/libm-i387/e_pow.S b/sysdeps/libm-i387/e_pow.S
index f6c7562d9c..efe184168b 100644
--- a/sysdeps/libm-i387/e_pow.S
+++ b/sysdeps/libm-i387/e_pow.S
@@ -1,5 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -27,31 +27,77 @@
 #endif
 
 	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	ASM_SIZE_DIRECTIVE(infinity)
+	ASM_TYPE_DIRECTIVE(zero,@object)
+zero:	.double 0.0
+	ASM_SIZE_DIRECTIVE(zero)
+	ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	ASM_SIZE_DIRECTIVE(minf_mzero)
 	ASM_TYPE_DIRECTIVE(one,@object)
 one:	.double 1.0
 	ASM_SIZE_DIRECTIVE(one)
 	ASM_TYPE_DIRECTIVE(limit,@object)
 limit:	.double 0.29
 	ASM_SIZE_DIRECTIVE(limit)
+	ASM_TYPE_DIRECTIVE(nan,@object)
+nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	ASM_SIZE_DIRECTIVE(nan)
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
 #else
 #define MO(op) op
+#define MOX(op,x,f) op(,x,f)
 #endif
 
 	.text
 ENTRY(__ieee754_pow)
-	fldl	4(%esp)		// x
-	fldl	12(%esp)	// y : x
+	fldl	12(%esp)	// y
+	fxam
+	fnstsw
+	movb	%ah, %dl
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah	// is y == 0 ?
+	je	11f
+
+	cmpb	$0x05, %ah	// is y == ±inf ?
+	je	12f
+
+	cmpb	$0x01, %ah	// is y == NaN ?
+	je	30f
 
 #ifdef	PIC
 	call	1f
 1:	popl	%ecx
 	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
 #endif
+
+	fldl	4(%esp)		// x : y
+
 	subl	$8,%esp
 
+	fxam
+	fnstsw
+	movb	%ah, %dh
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	je	20f		// x is ±0
+
+	cmpb	$0x05, %ah
+	je	15f		// x is ±inf
+
+	fxch			// y : x
+
 	/* First see whether `y' is a natural number.  In this case we
 	   can use a more precise algorithm.  */
 	fld	%st		// y : y : x
@@ -63,13 +109,11 @@ ENTRY(__ieee754_pow)
 	jne	2f
 
 	/* OK, we have an integer value for y.  */
-	ftst			// y : x
-	fstp	%st(0)		// x
-	fnstsw
-	sahf
 	popl	%eax
 	popl	%edx
-	jnc	4f		// y >= 0, jump
+	orl	$0, %edx
+	fstp	%st(0)		// x
+	jns	4f		// y >= 0, jump
 	fdivrl	MO(one)		// 1/x		(now referred to as x)
 	negl	%eax
 	adcl	$0, %edx
@@ -87,7 +131,7 @@ ENTRY(__ieee754_pow)
 	orl	%edx, %ecx
 	jnz	6b
 	fstp	%st(0)		// ST*x
-	ret
+30:	ret
 
 	.align ALIGNARG(4)
 2:	/* y is a real number.  */
@@ -117,4 +161,161 @@ ENTRY(__ieee754_pow)
 	addl	$8, %esp
 	fstp	%st(1)		// 2^fract(y*log2(x))*2^int(y*log2(x))
 	ret
+
+
+	// pow(x,±0) = 1
+	.align ALIGNARG(4)
+11:	fstp	%st(0)		// pop y
+	fldl	MO(one)
+	ret
+
+	// y == ±inf
+	.align ALIGNARG(4)
+12:	fstp	%st(0)		// pop y
+	fldl	4(%esp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x45, %ah
+	je	13f		// jump if x is NaN
+
+	cmpb	$0x40, %ah
+	je	14f		// jump if |x| == 1
+
+	shlb	$1, %ah
+	xorb	%ah, %dl
+	andl	$2, %edx
+	fldl	MOX(inf_zero, %edx, 4)
+	ret
+
+	.align ALIGNARG(4)
+14:	fldl	MO(nan)
+	faddl	MO(zero)	// raise invalid exception
+	ret
+
+	.align ALIGNARG(4)
+13:	fldl	4(%esp)		// load x == NaN
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±inf
+15:	fstp	%st(0)		// y
+	testb	$2, %dh
+	jz	16f		// jump if x == +inf
+
+	// We must find out whether y is an odd integer.
+	fld	%st		// y : y
+	fistpll	(%esp)		// y
+	fildll	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	17f
+
+	// OK, the value is an integer, but is the number of bits small
+	// enough so that all are coming from the mantissa?
+	popl	%eax
+	popl	%edx
+	andb	$1, %al
+	jz	18f		// jump if not odd
+	movl	%edx, %eax
+	orl	%edx, %edx
+	jns	155f
+	negl	%eax
+155:	cmpl	$0x00200000, %eax
+	ja	18f		// does not fit in mantissa bits
+	// It's an odd integer.
+	shrl	$31, %edx
+	fldl	MOX(minf_mzero, %edx, 8)
+	ret
+
+	.align ALIGNARG(4)
+16:	fcompl	MO(zero)
+	addl	$8, %esp
+	fnstsw
+	shrl	$5, %eax
+	andl	$8, %eax
+	fldl	MOX(inf_zero, %eax, 1)
+	ret
+
+	.align ALIGNARG(4)
+17:	shll	$30, %edx	// sign bit for y in right position
+	addl	$8, %esp
+18:	shrl	$31, %edx
+	fldl	MOX(inf_zero, %edx, 8)
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±0
+20:	fstp	%st(0)		// y
+	testb	$2, %dl
+	jz	21f		// y > 0
+
+	// x is ±0 and y is < 0.  We must find out whether y is an odd integer.
+	testb	$2, %dh
+	jz	25f
+
+	fld	%st		// y : y
+	fistpll	(%esp)		// y
+	fildll	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	26f
+
+	// OK, the value is an integer, but is the number of bits small
+	// enough so that all are coming from the mantissa?
+	popl	%eax
+	popl	%edx
+	andb	$1, %al
+	jz	27f		// jump if not odd
+	cmpl	$0xffe00000, %edx
+	jbe	27f		// does not fit in mantissa bits
+	// It's an odd integer.
+	// Raise divide-by-zero exception and get minus infinity value.
+	fldl	MO(one)
+	fdivl	MO(zero)
+	fchs
+	ret
+
+25:	fstp	%st(0)
+26:	popl	%eax
+	popl	%edx
+27:	// Raise divide-by-zero exception and get infinity value.
+	fldl	MO(one)
+	fdivl	MO(zero)
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±0 and y is > 0.  We must find out whether y is an odd integer.
+21:	testb	$2, %dh
+	jz	22f
+
+	fld	%st		// y : y
+	fistpll	(%esp)		// y
+	fildll	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	23f
+
+	// OK, the value is an integer, but is the number of bits small
+	// enough so that all are coming from the mantissa?
+	popl	%eax
+	popl	%edx
+	andb	$1, %al
+	jz	24f		// jump if not odd
+	cmpl	$0xffe00000, %edx
+	jbe	24f		// does not fit in mantissa bits
+	// It's an odd integer.
+	fldl	MO(mzero)
+	ret
+
+22:	fstp	%st(0)
+23:	popl	%eax
+	popl	%edx
+24:	fldl	MO(zero)
+	ret
+
 END(__ieee754_pow)
diff --git a/sysdeps/libm-i387/e_powf.S b/sysdeps/libm-i387/e_powf.S
index 9d6bc510b6..54af93c961 100644
--- a/sysdeps/libm-i387/e_powf.S
+++ b/sysdeps/libm-i387/e_powf.S
@@ -1,5 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -27,67 +27,107 @@
 #endif
 
 	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	ASM_SIZE_DIRECTIVE(infinity)
+	ASM_TYPE_DIRECTIVE(zero,@object)
+zero:	.double 0.0
+	ASM_SIZE_DIRECTIVE(zero)
+	ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	ASM_SIZE_DIRECTIVE(minf_mzero)
 	ASM_TYPE_DIRECTIVE(one,@object)
 one:	.double 1.0
 	ASM_SIZE_DIRECTIVE(one)
 	ASM_TYPE_DIRECTIVE(limit,@object)
 limit:	.double 0.29
 	ASM_SIZE_DIRECTIVE(limit)
+	ASM_TYPE_DIRECTIVE(nan,@object)
+nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	ASM_SIZE_DIRECTIVE(nan)
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
 #else
 #define MO(op) op
+#define MOX(op,x,f) op(,x,f)
 #endif
 
 	.text
 ENTRY(__ieee754_powf)
-	flds	4(%esp)		// x
-	flds	8(%esp)		// y : x
+	flds	8(%esp)	// y
+	fxam
+	fnstsw
+	movb	%ah, %dl
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah	// is y == 0 ?
+	je	11f
+
+	cmpb	$0x05, %ah	// is y == ±inf ?
+	je	12f
+
+	cmpb	$0x01, %ah	// is y == NaN ?
+	je	30f
 
 #ifdef	PIC
 	call	1f
 1:	popl	%ecx
 	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
 #endif
-	subl	$8,%esp
+
+	flds	4(%esp)		// x : y
+
+	subl	$4, %esp
+
+	fxam
+	fnstsw
+	movb	%ah, %dh
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	je	20f		// x is ±0
+
+	cmpb	$0x05, %ah
+	je	15f		// x is ±inf
+
+	fxch			// y : x
 
 	/* First see whether `y' is a natural number.  In this case we
 	   can use a more precise algorithm.  */
 	fld	%st		// y : y : x
-	fistpll	(%esp)		// y : x
-	fildll	(%esp)		// int(y) : y : x
+	fistpl	(%esp)		// y : x
+	fildl	(%esp)		// int(y) : y : x
 	fucomp	%st(1)		// y : x
 	fnstsw
 	sahf
 	jne	2f
 
 	/* OK, we have an integer value for y.  */
-	ftst			// y : x
-	fstp	%st(0)		// x
-	fnstsw
-	sahf
-	popl	%eax
 	popl	%edx
-	jnc	4f		// y >= 0, jump
+	orl	$0, %edx
+	fstp	%st(0)		// x
+	jns	4f		// y >= 0, jump
 	fdivrl	MO(one)		// 1/x		(now referred to as x)
-	negl	%eax
-	adcl	$0, %edx
 	negl	%edx
 4:	fldl	MO(one)		// 1 : x
 	fxch
 
-6:	shrdl	$1, %edx, %eax
+6:	shrl	$1, %edx
 	jnc	5f
 	fxch
 	fmul	%st(1)		// x : ST*x
 	fxch
 5:	fmul	%st(0), %st	// x*x : ST*x
-	movl	%eax, %ecx
-	orl	%edx, %ecx
+	testl	%edx, %edx
 	jnz	6b
 	fstp	%st(0)		// ST*x
-	ret
+30:	ret
 
 	.align ALIGNARG(4)
 2:	/* y is a real number.  */
@@ -114,7 +154,159 @@ ENTRY(__ieee754_powf)
 	f2xm1			// 2^fract(y*log2(x))-1 : int(y*log2(x))
 	faddl	MO(one)		// 2^fract(y*log2(x)) : int(y*log2(x))
 	fscale			// 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
-	addl	$8, %esp
+	addl	$4, %esp
 	fstp	%st(1)		// 2^fract(y*log2(x))*2^int(y*log2(x))
 	ret
+
+
+	// pow(x,±0) = 1
+	.align ALIGNARG(4)
+11:	fstp	%st(0)		// pop y
+	fldl	MO(one)
+	ret
+
+	// y == ±inf
+	.align ALIGNARG(4)
+12:	fstp	%st(0)		// pop y
+	flds	4(%esp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x45, %ah
+	je	13f		// jump if x is NaN
+
+	cmpb	$0x40, %ah
+	je	14f		// jump if |x| == 1
+
+	shlb	$1, %ah
+	xorb	%ah, %dl
+	andl	$2, %edx
+	fldl	MOX(inf_zero, %edx, 4)
+	ret
+
+	.align ALIGNARG(4)
+14:	fldl	MO(nan)
+	faddl	MO(zero)	// raise invalid exception
+	ret
+
+	.align ALIGNARG(4)
+13:	flds	4(%esp)		// load x == NaN
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±inf
+15:	fstp	%st(0)		// y
+	testb	$2, %dh
+	jz	16f		// jump if x == +inf
+
+	// We must find out whether y is an odd integer.
+	fld	%st		// y : y
+	fistpl	(%esp)		// y
+	fildl	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	17f
+
+	// OK, the value is an integer, but is the number of bits small
+	// enough so that all are coming from the mantissa?
+	popl	%edx
+	testb	$1, %dl
+	jz	18f		// jump if not odd
+	movl	%edx, %eax
+	orl	%edx, %edx
+	jns	155f
+	negl	%eax
+155:	cmpl	$0x01000000, %eax
+	ja	18f		// does not fit in mantissa bits
+	// It's an odd integer.
+	shrl	$31, %edx
+	fldl	MOX(minf_mzero, %edx, 8)
+	ret
+
+	.align ALIGNARG(4)
+16:	fcompl	MO(zero)
+	addl	$4, %esp
+	fnstsw
+	shrl	$5, %eax
+	andl	$8, %eax
+	fldl	MOX(inf_zero, %eax, 1)
+	ret
+
+	.align ALIGNARG(4)
+17:	shll	$30, %edx	// sign bit for y in right position
+	addl	$4, %esp
+18:	shrl	$31, %edx
+	fldl	MOX(inf_zero, %edx, 8)
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±0
+20:	fstp	%st(0)		// y
+	testb	$2, %dl
+	jz	21f		// y > 0
+
+	// x is ±0 and y is < 0.  We must find out whether y is an odd integer.
+	testb	$2, %dh
+	jz	25f
+
+	fld	%st		// y : y
+	fistpl	(%esp)		// y
+	fildl	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	26f
+
+	// OK, the value is an integer, but is the number of bits small
+	// enough so that all are coming from the mantissa?
+	popl	%edx
+	testb	$1, %dl
+	jz	27f		// jump if not odd
+	cmpl	$0xff000000, %edx
+	jbe	27f		// does not fit in mantissa bits
+	// It's an odd integer.
+	// Raise divide-by-zero exception and get minus infinity value.
+	fldl	MO(one)
+	fdivl	MO(zero)
+	fchs
+	ret
+
+25:	fstp	%st(0)
+26:	popl	%eax
+27:	// Raise divide-by-zero exception and get infinity value.
+	fldl	MO(one)
+	fdivl	MO(zero)
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±0 and y is > 0.  We must find out whether y is an odd integer.
+21:	testb	$2, %dh
+	jz	22f
+
+	fld	%st		// y : y
+	fistpl	(%esp)		// y
+	fildl	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	23f
+
+	// OK, the value is an integer, but is the number of bits small
+	// enough so that all are coming from the mantissa?
+	popl	%edx
+	testb	$1, %dl
+	jz	24f		// jump if not odd
+	cmpl	$0xff000000, %edx
+	jbe	24f		// does not fit in mantissa bits
+	// It's an odd integer.
+	fldl	MO(mzero)
+	ret
+
+22:	fstp	%st(0)
+23:	popl	%eax
+24:	fldl	MO(zero)
+	ret
+
 END(__ieee754_powf)
diff --git a/sysdeps/libm-i387/e_powl.S b/sysdeps/libm-i387/e_powl.S
index ea445804f0..3cfb96b213 100644
--- a/sysdeps/libm-i387/e_powl.S
+++ b/sysdeps/libm-i387/e_powl.S
@@ -1,5 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -27,31 +27,77 @@
 #endif
 
 	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	ASM_SIZE_DIRECTIVE(infinity)
+	ASM_TYPE_DIRECTIVE(zero,@object)
+zero:	.double 0.0
+	ASM_SIZE_DIRECTIVE(zero)
+	ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	ASM_SIZE_DIRECTIVE(minf_mzero)
 	ASM_TYPE_DIRECTIVE(one,@object)
 one:	.double 1.0
 	ASM_SIZE_DIRECTIVE(one)
 	ASM_TYPE_DIRECTIVE(limit,@object)
 limit:	.double 0.29
 	ASM_SIZE_DIRECTIVE(limit)
+	ASM_TYPE_DIRECTIVE(nan,@object)
+nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	ASM_SIZE_DIRECTIVE(nan)
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
 #else
 #define MO(op) op
+#define MOX(op,x,f) op(,x,f)
 #endif
 
 	.text
 ENTRY(__ieee754_powl)
-	fldt	4(%esp)		// x
-	fldt	16(%esp)	// y : x
+	fldt	16(%esp)	// y
+	fxam
+	fnstsw
+	movb	%ah, %dl
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah	// is y == 0 ?
+	je	11f
+
+	cmpb	$0x05, %ah	// is y == ±inf ?
+	je	12f
+
+	cmpb	$0x01, %ah	// is y == NaN ?
+	je	30f
 
 #ifdef	PIC
 	call	1f
 1:	popl	%ecx
 	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
 #endif
+
+	fldt	4(%esp)		// x : y
+
 	subl	$8,%esp
 
+	fxam
+	fnstsw
+	movb	%ah, %dh
+	andb	$0x45, %ah
+	cmpb	$0x40, %ah
+	je	20f		// x is ±0
+
+	cmpb	$0x05, %ah
+	je	15f		// x is ±inf
+
+	fxch			// y : x
+
 	/* First see whether `y' is a natural number.  In this case we
 	   can use a more precise algorithm.  */
 	fld	%st		// y : y : x
@@ -63,13 +109,11 @@ ENTRY(__ieee754_powl)
 	jne	2f
 
 	/* OK, we have an integer value for y.  */
-	ftst			// y : x
-	fstp	%st(0)		// x
-	fnstsw
-	sahf
 	popl	%eax
 	popl	%edx
-	jnc	4f		// y >= 0, jump
+	orl	$0, %edx
+	fstp	%st(0)		// x
+	jns	4f		// y >= 0, jump
 	fdivrl	MO(one)		// 1/x		(now referred to as x)
 	negl	%eax
 	adcl	$0, %edx
@@ -87,7 +131,7 @@ ENTRY(__ieee754_powl)
 	orl	%edx, %ecx
 	jnz	6b
 	fstp	%st(0)		// ST*x
-	ret
+30:	ret
 
 	.align ALIGNARG(4)
 2:	/* y is a real number.  */
@@ -117,4 +161,148 @@ ENTRY(__ieee754_powl)
 	addl	$8, %esp
 	fstp	%st(1)		// 2^fract(y*log2(x))*2^int(y*log2(x))
 	ret
+
+
+	// pow(x,±0) = 1
+	.align ALIGNARG(4)
+11:	fstp	%st(0)		// pop y
+	fldl	MO(one)
+	ret
+
+	// y == ±inf
+	.align ALIGNARG(4)
+12:	fstp	%st(0)		// pop y
+	fldt	4(%esp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x45, %ah
+	je	13f		// jump if x is NaN
+
+	cmpb	$0x40, %ah
+	je	14f		// jump if |x| == 1
+
+	shlb	$1, %ah
+	xorb	%ah, %dl
+	andl	$2, %edx
+	fldl	MOX(inf_zero, %edx, 4)
+	ret
+
+	.align ALIGNARG(4)
+14:	fldl	MO(nan)
+	faddl	MO(zero)	// raise invalid exception
+	ret
+
+	.align ALIGNARG(4)
+13:	fldt	4(%esp)		// load x == NaN
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±inf
+15:	fstp	%st(0)		// y
+	testb	$2, %dh
+	jz	16f		// jump if x == +inf
+
+	// We must find out whether y is an odd integer.
+	fld	%st		// y : y
+	fistpll	(%esp)		// y
+	fildll	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	17f
+
+	// OK, the value is an integer, but is it odd?
+	popl	%eax
+	popl	%edx
+	andb	$1, %al
+	jz	18f		// jump if not odd
+	// It's an odd integer.
+	shrl	$31, %edx
+	fldl	MOX(minf_mzero, %edx, 8)
+	ret
+
+	.align ALIGNARG(4)
+16:	fcompl	MO(zero)
+	addl	$8, %esp
+	fnstsw
+	shrl	$5, %eax
+	andl	$8, %eax
+	fldl	MOX(inf_zero, %eax, 1)
+	ret
+
+	.align ALIGNARG(4)
+17:	shll	$30, %edx	// sign bit for y in right position
+	addl	$8, %esp
+18:	shrl	$31, %edx
+	fldl	MOX(inf_zero, %edx, 8)
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±0
+20:	fstp	%st(0)		// y
+	testb	$2, %dl
+	jz	21f		// y > 0
+
+	// x is ±0 and y is < 0.  We must find out whether y is an odd integer.
+	testb	$2, %dh
+	jz	25f
+
+	fld	%st		// y : y
+	fistpll	(%esp)		// y
+	fildll	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	26f
+
+	// OK, the value is an integer, but is it odd?
+	popl	%eax
+	popl	%edx
+	andb	$1, %al
+	jz	27f		// jump if not odd
+	// It's an odd integer.
+	// Raise divide-by-zero exception and get minus infinity value.
+	fldl	MO(one)
+	fdivl	MO(zero)
+	fchs
+	ret
+
+25:	fstp	%st(0)
+26:	popl	%eax
+	popl	%edx
+27:	// Raise divide-by-zero exception and get infinity value.
+	fldl	MO(one)
+	fdivl	MO(zero)
+	ret
+
+	.align ALIGNARG(4)
+	// x is ±0 and y is > 0.  We must find out whether y is an odd integer.
+21:	testb	$2, %dh
+	jz	22f
+
+	fld	%st		// y : y
+	fistpll	(%esp)		// y
+	fildll	(%esp)		// int(y) : y
+	fucompp			// <empty>
+	fnstsw
+	sahf
+	jne	23f
+
+	// OK, the value is an integer, but is it odd?
+	popl	%eax
+	popl	%edx
+	andb	$1, %al
+	jz	24f		// jump if not odd
+	// It's an odd integer.
+	fldl	MO(mzero)
+	ret
+
+22:	fstp	%st(0)
+23:	popl	%eax
+	popl	%edx
+24:	fldl	MO(zero)
+	ret
+
 END(__ieee754_powl)
diff --git a/sysdeps/libm-i387/s_expm1.S b/sysdeps/libm-i387/s_expm1.S
index 78e8013b7e..e1b198d604 100644
--- a/sysdeps/libm-i387/s_expm1.S
+++ b/sysdeps/libm-i387/s_expm1.S
@@ -30,9 +30,9 @@
 	.text
 #endif
 	.align ALIGNARG(4)
-	ASM_TYPE_DIRECTIVE(zero,@object)
-zero:	.double 0.0
-	ASM_SIZE_DIRECTIVE(zero)
+	ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1:	.double -1.0
+	ASM_SIZE_DIRECTIVE(minus1)
 	ASM_TYPE_DIRECTIVE(one,@object)
 one:	.double 1.0
 	ASM_SIZE_DIRECTIVE(one)
@@ -79,7 +79,8 @@ ENTRY(__expm1)
 
 2:	testl	$0x200, %eax	// Test sign.
 	jz	3f		// If positive, jump.
-	fldl	MO(zero)	// Set result to 0.
+	fstp	%st
+	fldl	MO(minus1)	// Set result to -1.0.
 3:	ret
 END(__expm1)
 weak_alias (__expm1, expm1)
diff --git a/sysdeps/libm-i387/s_expm1f.S b/sysdeps/libm-i387/s_expm1f.S
index 00f1562e73..8626fee45d 100644
--- a/sysdeps/libm-i387/s_expm1f.S
+++ b/sysdeps/libm-i387/s_expm1f.S
@@ -30,9 +30,9 @@
 	.text
 #endif
 	.align ALIGNARG(4)
-	ASM_TYPE_DIRECTIVE(zero,@object)
-zero:	.double 0.0
-	ASM_SIZE_DIRECTIVE(zero)
+	ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1:	.double -1.0
+	ASM_SIZE_DIRECTIVE(minus1)
 	ASM_TYPE_DIRECTIVE(one,@object)
 one:	.double 1.0
 	ASM_SIZE_DIRECTIVE(one)
@@ -79,7 +79,8 @@ ENTRY(__expm1f)
 
 2:	testl	$0x200, %eax	// Test sign.
 	jz	3f		// If positive, jump.
-	fldl	MO(zero)	// Set result to 0.
+	fstp	%st
+	fldl	MO(minus1)	// Set result to -1.0.
 3:	ret
 END(__expm1f)
 weak_alias (__expm1f, expm1f)
diff --git a/sysdeps/libm-i387/s_expm1l.S b/sysdeps/libm-i387/s_expm1l.S
index b7e6b36d39..46290ca4a9 100644
--- a/sysdeps/libm-i387/s_expm1l.S
+++ b/sysdeps/libm-i387/s_expm1l.S
@@ -30,9 +30,9 @@
 	.text
 #endif
 	.align ALIGNARG(4)
-	ASM_TYPE_DIRECTIVE(zero,@object)
-zero:	.double 0.0
-	ASM_SIZE_DIRECTIVE(zero)
+	ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1:	.double -1.0
+	ASM_SIZE_DIRECTIVE(minus1)
 	ASM_TYPE_DIRECTIVE(one,@object)
 one:	.double 1.0
 	ASM_SIZE_DIRECTIVE(one)
@@ -79,7 +79,8 @@ ENTRY(__expm1l)
 
 2:	testl	$0x200, %eax	// Test sign.
 	jz	3f		// If positive, jump.
-	fldl	MO(zero)	// Set result to 0.
+	fstp	%st
+	fldl	MO(minus1)	// Set result to -1.0.
 3:	ret
 END(__expm1l)
 weak_alias (__expm1l, expm1l)
diff --git a/sysdeps/libm-i387/s_isinfl.c b/sysdeps/libm-i387/s_isinfl.c
index 3ee53d5ecc..f07898fd1b 100644
--- a/sysdeps/libm-i387/s_isinfl.c
+++ b/sysdeps/libm-i387/s_isinfl.c
@@ -10,7 +10,7 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 /*
- * isinfl(x) returns 1 is x is inf, else 0;
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
  * no branching!
  */
 
@@ -26,11 +26,11 @@ static char rcsid[] = "$NetBSD: $";
 {
 	int32_t se,hx,lx;
 	GET_LDOUBLE_WORDS(se,hx,lx,x);
-	se &= 0x7fff;
-	se ^= 0x7fff;
 	/* This additional ^ 0x80000000 is necessary because in Intel's
-	   internal representation the implicit one is explicit.  */
-	se |= (hx ^ 0x80000000) | lx;
-	return (se == 0);
+	   internal representation of the implicit one is explicit.  */
+	lx |= (hx ^ 0x80000000) | ((se & 0x7fff) ^ 0x7fff);
+	lx |= -lx;
+	se &= 0x8000;
+	return ~(lx >> 31) & (1 - (se >> 14));
 }
 weak_alias (__isinfl, isinfl)
diff --git a/sysdeps/libm-i387/s_logbl.S b/sysdeps/libm-i387/s_logbl.S
index 6ce274c57c..5c9a9c1c9d 100644
--- a/sysdeps/libm-i387/s_logbl.S
+++ b/sysdeps/libm-i387/s_logbl.S
@@ -11,6 +11,7 @@ RCSID("$NetBSD: $")
 ENTRY(__logbl)
 	fldt	4(%esp)
 	fxtract
+	fstp	%st
 	ret
 END (__logbl)
 weak_alias (__logbl, logbl)
diff --git a/sysdeps/libm-i387/s_scalbn.S b/sysdeps/libm-i387/s_scalbn.S
index 3ec56d4523..709b7a47f5 100644
--- a/sysdeps/libm-i387/s_scalbn.S
+++ b/sysdeps/libm-i387/s_scalbn.S
@@ -11,6 +11,7 @@ ENTRY(__scalbn)
 	fildl	12(%esp)
 	fldl	4(%esp)
 	fscale
+	fstp	%st(1)
 	ret
 END (__scalbn)
 weak_alias (__scalbn, scalbn)
diff --git a/sysdeps/libm-i387/s_scalbnf.S b/sysdeps/libm-i387/s_scalbnf.S
index b1a1c46b6c..ce92113844 100644
--- a/sysdeps/libm-i387/s_scalbnf.S
+++ b/sysdeps/libm-i387/s_scalbnf.S
@@ -11,6 +11,7 @@ ENTRY(__scalbnf)
 	fildl	8(%esp)
 	flds	4(%esp)
 	fscale
+	fstp	%st(1)
 	ret
 END (__scalbnf)
 weak_alias (__scalbnf, scalbnf)
diff --git a/sysdeps/libm-i387/s_scalbnl.S b/sysdeps/libm-i387/s_scalbnl.S
index 0f3323803c..09e06457b8 100644
--- a/sysdeps/libm-i387/s_scalbnl.S
+++ b/sysdeps/libm-i387/s_scalbnl.S
@@ -12,6 +12,7 @@ ENTRY(__scalbnl)
 	fildl	16(%esp)
 	fldt	4(%esp)
 	fscale
+	fstp	%st(1)
 	ret
 END (__scalbnl)
 weak_alias (__scalbnl, scalbnl)
diff --git a/sysdeps/libm-ieee754/e_atan2l.c b/sysdeps/libm-ieee754/e_atan2l.c
new file mode 100644
index 0000000000..6b76f96533
--- /dev/null
+++ b/sysdeps/libm-ieee754/e_atan2l.c
@@ -0,0 +1,136 @@
+/* e_atan2l.c -- long double version of e_atan2.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* __ieee754_atan2l(y,x)
+ * Method :
+ *	1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ *	2. Reduce x to positive by (if x and y are unexceptional):
+ *		ARG (x+iy) = arctan(y/x)   	   ... if x > 0,
+ *		ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
+ *
+ * Special cases:
+ *
+ *	ATAN2((anything), NaN ) is NaN;
+ *	ATAN2(NAN , (anything) ) is NaN;
+ *	ATAN2(+-0, +(anything but NaN)) is +-0  ;
+ *	ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ *	ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ *	ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ *	ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ *	ATAN2(+-INF,+INF ) is +-pi/4 ;
+ *	ATAN2(+-INF,-INF ) is +-3pi/4;
+ *	ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny  = 1.0e-4900L,
+zero  = 0.0,
+pi_o_4  = 7.85398163397448309628202E-01L, /* 0x3FFE, 0xC90FDAA2, 0x2168C235 */
+pi_o_2  = 1.5707963267948966192564E+00L,  /* 0x3FFF, 0xC90FDAA2, 0x2168C235 */
+pi      = 3.14159265358979323851281E+00L, /* 0x4000, 0xC90FDAA2, 0x2168C235 */
+pi_lo   = -5.01655761266833202345176e-20L;/* 0xBFBE, 0xECE675D1, 0xFC8F8CBB */
+
+#ifdef __STDC__
+	long double __ieee754_atan2l(long double y, long double x)
+#else
+	long double __ieee754_atan2l(y,x)
+	long double  y,x;
+#endif
+{
+	long double z;
+	int32_t k,m,hx,hy,ix,iy;
+	u_int32_t sx,sy,lx,ly;
+
+	EXTRACT_LDOUBLE_WORDS(sx,hx,lx,x);
+	ix = sx&0x7fff;
+	lx |= hx ^ 0x80000000;
+	EXTRACT_LDOUBLE_WORDS(sy,hy,ly,y);
+	iy = sy&0x7fff;
+	ly |= hy ^ 0x80000000;
+	if(((2*ix|((lx|-lx)>>31))>0xfffe)||
+	   ((2*iy|((ly|-ly)>>31))>0xfffe))	/* x or y is NaN */
+	   return x+y;
+	if((sx-0x3fff|lx)==0) return __atanl(y);   /* x=1.0 */
+	m = ((sy>>15)&1)|((sx>>14)&2);	/* 2*sign(x)+sign(y) */
+
+    /* when y = 0 */
+	if((iy|ly)==0) {
+	    switch(m) {
+		case 0:
+		case 1: return y; 	/* atan(+-0,+anything)=+-0 */
+		case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
+		case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+	    }
+	}
+    /* when x = 0 */
+	if((ix|lx)==0) return (sy>=0x8000)?  -pi_o_2-tiny: pi_o_2+tiny;
+
+    /* when x is INF */
+	if(ix==0x7fff) {
+	    if(iy==0x7fff) {
+		switch(m) {
+		    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
+		    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+		    case 2: return  3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+		    case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+		}
+	    } else {
+		switch(m) {
+		    case 0: return  zero  ;	/* atan(+...,+INF) */
+		    case 1: return -zero  ;	/* atan(-...,+INF) */
+		    case 2: return  pi+tiny  ;	/* atan(+...,-INF) */
+		    case 3: return -pi-tiny  ;	/* atan(-...,-INF) */
+		}
+	    }
+	}
+    /* when y is INF */
+	if(iy==0x7fff) return (hy>=0x8000)? -pi_o_2-tiny: pi_o_2+tiny;
+
+    /* compute y/x */
+	k = sy-sx;
+	if(k > 70) z=pi_o_2+0.5*pi_lo; 	/* |y/x| >  2**70 */
+	else if(sx>=0x8000&&k<-70) z=0.0; 	/* |y|/x < -2**70 */
+	else z=__atanl(fabsl(y/x));	/* safe to do y/x */
+	switch (m) {
+	    case 0: return       z  ;	/* atan(+,+) */
+	    case 1: {
+	    	      u_int32_t sz;
+		      GET_LDOUBLE_EXP(sz,z);
+		      SET_LDOUBLE_EXP(z,sy ^ 0x8000);
+		    }
+		    return       z  ;	/* atan(-,+) */
+	    case 2: return  pi-(z-pi_lo);/* atan(+,-) */
+	    default: /* case 3 */
+	    	    return  (z-pi_lo)-pi;/* atan(-,-) */
+	}
+}
diff --git a/sysdeps/libm-ieee754/s_fpclassifyl.c b/sysdeps/libm-ieee754/s_fpclassifyl.c
index ef37e6f0cc..d7a0e943cf 100644
--- a/sysdeps/libm-ieee754/s_fpclassifyl.c
+++ b/sysdeps/libm-ieee754/s_fpclassifyl.c
@@ -30,6 +30,7 @@ __fpclassifyl (long double x)
   int retval = FP_NORMAL;
 
   GET_LDOUBLE_WORDS (ex, hx, lx, x);
+  hx &= 0x7fffffff;
   hx |= lx;
   ex &= 0x7fff;
   if ((ex | hx) == 0)
diff --git a/sysdeps/libm-ieee754/s_isinf.c b/sysdeps/libm-ieee754/s_isinf.c
index b35fc1c41c..d3c2cb55b7 100644
--- a/sysdeps/libm-ieee754/s_isinf.c
+++ b/sysdeps/libm-ieee754/s_isinf.c
@@ -1,5 +1,6 @@
 /*
  * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changed to return -1 for -Inf by Ulrich Drepper <drepper@cygnus.com>.
  * Public domain.
  */
 
@@ -8,7 +9,7 @@ static char rcsid[] = "$NetBSD: s_isinf.c,v 1.3 1995/05/11 23:20:14 jtc Exp $";
 #endif
 
 /*
- * isinf(x) returns 1 is x is inf, else 0;
+ * isinf(x) returns 1 is x is inf, -1 if x is -inf, else 0;
  * no branching!
  */
 
@@ -22,12 +23,12 @@ static char rcsid[] = "$NetBSD: s_isinf.c,v 1.3 1995/05/11 23:20:14 jtc Exp $";
 	double x;
 #endif
 {
-	int32_t hx,lx;
+	u_int32_t hx;
+	int32_t lx;
 	EXTRACT_WORDS(hx,lx,x);
-	hx &= 0x7fffffff;
-	hx ^= 0x7ff00000;
-	hx |= lx;
-	return (hx == 0);
+	lx |= (hx & 0x7fffffff) ^ 0x7ff00000;
+	lx |= -lx;
+	return ~(lx >> 31) & (1 - ((hx >> 30) & 2));
 }
 weak_alias (__isinf, isinf)
 #ifdef NO_LONG_DOUBLE
diff --git a/sysdeps/libm-ieee754/s_isinff.c b/sysdeps/libm-ieee754/s_isinff.c
index 1d81f15986..9acc0df6ec 100644
--- a/sysdeps/libm-ieee754/s_isinff.c
+++ b/sysdeps/libm-ieee754/s_isinff.c
@@ -8,7 +8,7 @@ static char rcsid[] = "$NetBSD: s_isinff.c,v 1.3 1995/05/11 23:20:21 jtc Exp $";
 #endif
 
 /*
- * isinff(x) returns 1 is x is inf, else 0;
+ * isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
  * no branching!
  */
 
@@ -22,10 +22,11 @@ static char rcsid[] = "$NetBSD: s_isinff.c,v 1.3 1995/05/11 23:20:21 jtc Exp $";
 	float x;
 #endif
 {
-	int32_t ix;
+	int32_t ix,t;
 	GET_FLOAT_WORD(ix,x);
-	ix &= 0x7fffffff;
-	ix ^= 0x7f800000;
-	return (ix == 0);
+	t = ix & 0x7fffffff;
+	t ^= 0x7f800000;
+	t |= -t;
+	return ~(t >> 31) & (1 - ((ix & 0x80000000) >> 30));
 }
 weak_alias (__isinff, isinff)
diff --git a/sysdeps/libm-ieee754/s_isinfl.c b/sysdeps/libm-ieee754/s_isinfl.c
index 22dff75444..b499821441 100644
--- a/sysdeps/libm-ieee754/s_isinfl.c
+++ b/sysdeps/libm-ieee754/s_isinfl.c
@@ -9,7 +9,7 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 /*
- * isinfl(x) returns 1 is x is inf, else 0;
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
  * no branching!
  */
 
@@ -25,9 +25,9 @@ static char rcsid[] = "$NetBSD: $";
 {
 	int32_t se,hx,lx;
 	GET_LDOUBLE_WORDS(se,hx,lx,x);
-	se &= 0x7fff;
-	se ^= 0x7fff;
-	se |= hx | lx;
-	return (se == 0);
+	hx |= lx | ((se & 0x7fff) ^ 0x7fff);
+	hx |= -hx;
+	se &= 0x8000;
+	return ~(hx >> 31) & (1 - (se >> 14));
 }
 weak_alias (__isinfl, isinfl)
diff --git a/sysdeps/libm-ieee754/s_scalbnl.c b/sysdeps/libm-ieee754/s_scalbnl.c
index d00eb88167..6825e9c7b3 100644
--- a/sysdeps/libm-ieee754/s_scalbnl.c
+++ b/sysdeps/libm-ieee754/s_scalbnl.c
@@ -33,10 +33,10 @@ static const long double
 #else
 static long double
 #endif
-two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
-huge   = 1.0e+300,
-tiny   = 1.0e-300;
+two54   =  1.80143985094819840000e+16, /* 0x4035, 0x00000000, 0x00000000 */
+twom54  =  5.55111512312578270212e-17, /* 0x3FC9, 0x00000000, 0x00000000 */
+huge   = 1.0e+4900L,
+tiny   = 1.0e-4900L;
 
 #ifdef __STDC__
 	long double __scalbnl (long double x, int n)
diff --git a/sysdeps/libm-ieee754/w_atan2.c b/sysdeps/libm-ieee754/w_atan2.c
index ec29d55eb9..3f6032f977 100644
--- a/sysdeps/libm-ieee754/w_atan2.c
+++ b/sysdeps/libm-ieee754/w_atan2.c
@@ -34,11 +34,10 @@ static char rcsid[] = "$NetBSD: w_atan2.c,v 1.6 1995/05/10 20:48:39 jtc Exp $";
 #else
 	double z;
 	z = __ieee754_atan2(y,x);
-	if(_LIB_VERSION == _IEEE_||__isnan(x)||__isnan(y)) return z;
+	if(_LIB_VERSION != _SVID_||__isnan(x)||__isnan(y)) return z;
 	if(x==0.0&&y==0.0) {
-	        return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */
-	} else
-	    return z;
+	  return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */
+	return z;
 #endif
 }
 weak_alias (__atan2, atan2)
diff --git a/sysdeps/libm-ieee754/w_atan2f.c b/sysdeps/libm-ieee754/w_atan2f.c
index 4d67638572..00b2ce7633 100644
--- a/sysdeps/libm-ieee754/w_atan2f.c
+++ b/sysdeps/libm-ieee754/w_atan2f.c
@@ -8,7 +8,7 @@
  *
  * Developed at SunPro, a Sun Microsystems, Inc. business.
  * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice 
+ * software is freely granted, provided that this notice
  * is preserved.
  * ====================================================
  */
@@ -17,7 +17,7 @@
 static char rcsid[] = "$NetBSD: w_atan2f.c,v 1.3 1995/05/10 20:48:42 jtc Exp $";
 #endif
 
-/* 
+/*
  * wrapper atan2f(y,x)
  */
 
@@ -38,11 +38,7 @@ static char rcsid[] = "$NetBSD: w_atan2f.c,v 1.3 1995/05/10 20:48:42 jtc Exp $";
 	float z;
 	z = __ieee754_atan2f(y,x);
 	if(_LIB_VERSION == _IEEE_||__isnanf(x)||__isnanf(y)) return z;
-	if(x==(float)0.0&&y==(float)0.0) {
-		/* atan2f(+-0,+-0) */
-	        return (float)__kernel_standard((double)y,(double)x,103);
-	} else
-	    return z;
+	return z;
 #endif
 }
 weak_alias (__atan2f, atan2f)
diff --git a/sysdeps/libm-ieee754/w_atan2l.c b/sysdeps/libm-ieee754/w_atan2l.c
index 9e6e56bbed..437a04c760 100644
--- a/sysdeps/libm-ieee754/w_atan2l.c
+++ b/sysdeps/libm-ieee754/w_atan2l.c
@@ -39,10 +39,7 @@ static char rcsid[] = "$NetBSD: $";
 	long double z;
 	z = __ieee754_atan2l(y,x);
 	if(_LIB_VERSION == _IEEE_||__isnanl(x)||__isnanl(y)) return z;
-	if(x==0.0&&y==0.0) {
-	        return __kernel_standard(y,x,203); /* atan2l(+-0,+-0) */
-	} else
-	    return z;
+	return z;
 #endif
 }
 weak_alias (__atan2l, atan2l)
diff --git a/sysdeps/libm-ieee754/w_pow.c b/sysdeps/libm-ieee754/w_pow.c
index ea19e1f554..1711d71bda 100644
--- a/sysdeps/libm-ieee754/w_pow.c
+++ b/sysdeps/libm-ieee754/w_pow.c
@@ -43,7 +43,10 @@
 	    if(y==0.0)
 	        return __kernel_standard(x,y,20); /* pow(0.0,0.0) */
 	    if(__finite(y)&&y<0.0)
-	        return __kernel_standard(x,y,23); /* pow(0.0,negative) */
+	      if (signbit (x) && signbit (z))
+	        return __kernel_standard(x,y,23); /* pow(-0.0,negative) */
+	      else
+	        return __kernel_standard(x,y,43); /* pow(+0.0,negative) */
 	    return z;
 	}
 	if(!__finite(z)) {
diff --git a/sysdeps/libm-ieee754/w_powf.c b/sysdeps/libm-ieee754/w_powf.c
index 3f9d5c8d5f..0b20822be8 100644
--- a/sysdeps/libm-ieee754/w_powf.c
+++ b/sysdeps/libm-ieee754/w_powf.c
@@ -8,7 +8,7 @@
  *
  * Developed at SunPro, a Sun Microsystems, Inc. business.
  * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice 
+ * software is freely granted, provided that this notice
  * is preserved.
  * ====================================================
  */
@@ -17,7 +17,7 @@
 static char rcsid[] = "$NetBSD: w_powf.c,v 1.3 1995/05/10 20:49:41 jtc Exp $";
 #endif
 
-/* 
+/*
  * wrapper powf(x,y) return x**y
  */
 
@@ -39,19 +39,22 @@ static char rcsid[] = "$NetBSD: w_powf.c,v 1.3 1995/05/10 20:49:41 jtc Exp $";
 	z=__ieee754_powf(x,y);
 	if(_LIB_VERSION == _IEEE_|| __isnanf(y)) return z;
 	if(__isnanf(x)) {
-	    if(y==(float)0.0) 
+	    if(y==(float)0.0)
 	        /* powf(NaN,0.0) */
 	        return (float)__kernel_standard((double)x,(double)y,142);
-	    else 
+	    else
 		return z;
 	}
-	if(x==(float)0.0){ 
+	if(x==(float)0.0){
 	    if(y==(float)0.0)
 	        /* powf(0.0,0.0) */
 	        return (float)__kernel_standard((double)x,(double)y,120);
 	    if(__finitef(y)&&y<(float)0.0)
+	      if (signbit (x) && signbit (z))
 	        /* powf(0.0,negative) */
 	        return (float)__kernel_standard((double)x,(double)y,123);
+	      else
+	        return (float)__kernel_standard((double)x,(double)y,143);
 	    return z;
 	}
 	if(!__finitef(z)) {
@@ -59,11 +62,11 @@ static char rcsid[] = "$NetBSD: w_powf.c,v 1.3 1995/05/10 20:49:41 jtc Exp $";
 	        if(__isnanf(z))
 		    /* powf neg**non-int */
 	            return (float)__kernel_standard((double)x,(double)y,124);
-	        else 
+	        else
 		    /* powf overflow */
 	            return (float)__kernel_standard((double)x,(double)y,121);
 	    }
-	} 
+	}
 	if(z==(float)0.0&&__finitef(x)&&__finitef(y))
 	    /* powf underflow */
 	    return (float)__kernel_standard((double)x,(double)y,122);
diff --git a/sysdeps/libm-ieee754/w_powl.c b/sysdeps/libm-ieee754/w_powl.c
index 019664e0f1..aea572d905 100644
--- a/sysdeps/libm-ieee754/w_powl.c
+++ b/sysdeps/libm-ieee754/w_powl.c
@@ -45,7 +45,10 @@
 	    if(y==0.0)
 	        return __kernel_standard(x,y,220); /* pow(0.0,0.0) */
 	    if(__finite(y)&&y<0.0)
-	        return __kernel_standard(x,y,223); /* pow(0.0,negative) */
+	      if (signbit (x) && signbit (z))
+	        return __kernel_standard(x,y,223); /* pow(-0.0,negative) */
+	      else
+	        return __kernel_standard(x,y,243); /* pow(+0.0,negative) */
 	    return z;
 	}
 	if(!__finitel(z)) {
diff --git a/sysdeps/m68k/huge_val.h b/sysdeps/m68k/huge_val.h
new file mode 100644
index 0000000000..c2139580e8
--- /dev/null
+++ b/sysdeps/m68k/huge_val.h
@@ -0,0 +1,92 @@
+/* `HUGE_VAL' constants for m68k (where it is infinity).
+   Used by <stdlib.h> and <math.h> functions for overflow.
+   Copyright (C) 1992, 1995, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef	   _HUGE_VAL_H
+#define	   _HUGE_VAL_H	1
+
+#include <features.h>
+#include <sys/cdefs.h>
+#include <endian.h>
+
+/* IEEE positive infinity (-HUGE_VAL is negative infinity).  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define	__HUGE_VAL_bytes	{ 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define	__HUGE_VAL_bytes	{ 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
+#endif
+
+#define __huge_val_t	union { unsigned char __c[8]; double __d; }
+#ifdef	__GNUC__
+#define	HUGE_VAL	(__extension__ \
+			 ((__huge_val_t) { __c: __HUGE_VAL_bytes }).__d)
+#else	/* Not GCC.  */
+static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
+#define	HUGE_VAL	(__huge_val.__d)
+#endif	/* GCC.  */
+
+
+/* ISO C 9X extensions: (float) HUGE_VALF and (long double) HUGE_VALL.  */
+
+#ifdef __USE_ISOC9X
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define	__HUGE_VALF_bytes	{ 0x7f, 0x80, 0, 0 }
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define	__HUGE_VALF_bytes	{ 0, 0, 0x80, 0x7f }
+#endif
+
+#define __huge_valf_t	union { unsigned char __c[4]; float __f; }
+#ifdef	__GNUC__
+#define	HUGE_VALF	(__extension__ \
+			 ((__huge_valf_t) { __c: __HUGE_VALF_bytes }).__f)
+#else	/* Not GCC.  */
+static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes };
+#define	HUGE_VALF	(__huge_valf.__f)
+#endif	/* GCC.  */
+
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define	__HUGE_VALL_bytes	{ 0x7f, 0xff, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define	__HUGE_VALL_bytes	{ 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7f, 0, 0 }
+#endif
+
+#define __huge_vall_t	union { unsigned char __c[12]; long double __ld; }
+#ifdef	__GNUC__
+#define	HUGE_VALL	(__extension__ \
+			 ((__huge_vall_t) { __c: __HUGE_VALL_bytes }).__ld)
+#else	/* Not GCC.  */
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+#define	HUGE_VALL	(__huge_vall.__ld)
+#endif	/* GCC.  */
+
+
+/* Expression representing positive infinity.  Here it is the same as
+   HUGE_VALF.  */
+#define INFINITY	HUGE_VALF
+
+#endif	/* __USE_ISOC9X.  */
+
+
+#endif	   /* huge_val.h */
diff --git a/sysdeps/mach/hurd/euidaccess.c b/sysdeps/mach/hurd/euidaccess.c
index bbd2d21afe..d206b8644c 100644
--- a/sysdeps/mach/hurd/euidaccess.c
+++ b/sysdeps/mach/hurd/euidaccess.c
@@ -1,5 +1,5 @@
 /* Test for access to FILE using effective UID and GID.  Hurd version.
-Copyright (C) 1991, 1995 Free Software Foundation, Inc.
+Copyright (C) 1991, 1995, 1997 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
@@ -24,7 +24,7 @@ Cambridge, MA 02139, USA.  */
 #include <hurd.h>
 
 int
-euidaccess (file, type)
+__euidaccess (file, type)
      const char *file;
      int type;
 {
@@ -56,3 +56,4 @@ euidaccess (file, type)
 
   return 0;
 }
+weak_alias (__euidaccess, euidaccess)
diff --git a/sysdeps/posix/isfdtype.c b/sysdeps/posix/isfdtype.c
index 8edcf594d8..ec4568e460 100644
--- a/sysdeps/posix/isfdtype.c
+++ b/sysdeps/posix/isfdtype.c
@@ -1,25 +1,26 @@
-/* isfdtype - Determine whether descriptor has given property.
-Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+/* Determine whether descriptor has given property.
+   Copyright (C) 1996, 1997 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 Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
+   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
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 
 int
 isfdtype (int fildes, int fdtype)
@@ -33,5 +34,5 @@ isfdtype (int fildes, int fdtype)
     __set_errno (save_error);
   }
 
-  return result ?: (st.st_mode & S_IFMT) == fdtype;
+  return result ?: (st.st_mode & S_IFMT) == (mode_t) fdtype;
 }
diff --git a/sysdeps/sparc/dl-machine.h b/sysdeps/sparc/dl-machine.h
index 5240b0cf81..6f1d7eb02e 100644
--- a/sysdeps/sparc/dl-machine.h
+++ b/sysdeps/sparc/dl-machine.h
@@ -98,8 +98,8 @@ elf_machine_load_address (void)
    MAP is the object containing the reloc.  */
 
 static inline void
-elf_machine_rela (struct link_map *map,
-		  const Elf32_Rela *reloc, const Elf32_Sym *sym)
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+		  const Elf32_Sym *sym, const struct r_found_version *version)
 {
   Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset);
   Elf32_Addr loadbase;
@@ -107,31 +107,31 @@ elf_machine_rela (struct link_map *map,
   switch (ELF32_R_TYPE (reloc->r_info))
     {
     case R_SPARC_COPY:
-      loadbase = RESOLVE (&sym, DL_LOOKUP_NOEXEC);
+      loadbase = RESOLVE (&sym, version, DL_LOOKUP_NOEXEC);
       memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
       break;
     case R_SPARC_GLOB_DAT:
     case R_SPARC_32:
-      loadbase = RESOLVE (&sym, 0);
+      loadbase = RESOLVE (&sym, version, 0);
       *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
 		     + reloc->r_addend);
       break;
     case R_SPARC_JMP_SLOT:
-      loadbase = RESOLVE (&sym, DL_LOOKUP_NOPLT);
+      loadbase = RESOLVE (&sym, version, DL_LOOKUP_NOPLT);
       {
 	Elf32_Addr value = ((sym ? (loadbase + sym->st_value) : 0)
 			    + reloc->r_addend);
-	reloc_addr[1] = OPCODE_SETHI | (value >> 10);
+	reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
 	reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
       }
       break;
     case R_SPARC_8:
-      loadbase = RESOLVE (&sym, 0);
+      loadbase = RESOLVE (&sym, version, 0);
       *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
 			      + reloc->r_addend);
       break;
     case R_SPARC_16:
-      loadbase = RESOLVE (&sym, 0);
+      loadbase = RESOLVE (&sym, version, 0);
       *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
 			       + reloc->r_addend);
       break;
@@ -139,19 +139,19 @@ elf_machine_rela (struct link_map *map,
       *reloc_addr += map->l_addr + reloc->r_addend;
       break;
     case R_SPARC_DISP8:
-      loadbase = RESOLVE (&sym, 0);
+      loadbase = RESOLVE (&sym, version, 0);
       *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
 			      + reloc->r_addend
 			      - (Elf32_Addr) reloc_addr);
       break;
     case R_SPARC_DISP16:
-      loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
+      loadbase = RESOLVE (&sym, version, 0);
       *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
 			       + reloc->r_addend
 			       - (Elf32_Addr) reloc_addr);
       break;
     case R_SPARC_DISP32:
-      loadbase = RESOLVE (&sym, 0);
+      loadbase = RESOLVE (&sym, version, 0);
       *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0)
 		     + reloc->r_addend
 		     - (Elf32_Addr) reloc_addr);
@@ -160,17 +160,27 @@ elf_machine_rela (struct link_map *map,
 	{
 	  unsigned int saddr;
 
-	  loadbase = RESOLVE (&sym, 0);
+	  loadbase = RESOLVE (&sym, version, 0);
 	  saddr = (loadbase ? loadbase : map->l_addr) + reloc->r_addend;
 
 	  *reloc_addr = (*reloc_addr & ~0x3ff) | (saddr & 0x3ff);
 	}
        break;
+    case R_SPARC_WDISP30:
+      {
+	unsigned int saddr;
+
+	loadbase = RESOLVE (&sym, version, 0);
+	saddr = (loadbase ? loadbase : map->l_addr) + reloc->r_addend;
+	*reloc_addr = ((*reloc_addr & 0xc0000000)
+		       | ((saddr - (unsigned int) reloc_addr)>>2));
+      }
+      break;
     case R_SPARC_HI22:
       {
 	unsigned int saddr;
 
-	loadbase = RESOLVE (&sym, 0);
+	loadbase = RESOLVE (&sym, version, 0);
 	saddr = (loadbase ? loadbase : map->l_addr) + reloc->r_addend;
 
 	*reloc_addr = (*reloc_addr & 0xffc00000)|(saddr >> 10);
@@ -199,9 +209,7 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
     }
 }
 
-#define ELF_ADJUST_ARG(arg) __asm__("\tadd %%fp,64,%0\n" : "=r" (arg))
-
-#endif	/* RESOLV */
+#endif	/* RESOLVE */
 
 /* Nonzero iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.  */
@@ -285,8 +293,49 @@ _dl_runtime_resolve:
  .globl _start\n\
  .type _start,@function\n\
 _start:\n\
+  /* Pass pointer to argument block to _dl_start.  */\n\
+  add %sp,64,%o0\n\
   call _dl_start\n\
-  nop\n\
-  call %o0\n\
+   nop\n\
+  \n\
+  mov %o0,%l0\n\
+  \n\
+2:\n\
+   call 1f\n\
+   nop\n\
+1:\n\
+  sethi %hi(_GLOBAL_OFFSET_TABLE_-(2b-.)),%l2\n\
+  sethi %hi(_dl_default_scope),%l3\n\
+  or    %l2,%lo(_GLOBAL_OFFSET_TABLE_-(2b-.)),%l2\n\
+  or    %l3,%lo(_dl_default_scope),%l3\n\
+  add   %o7,%l2,%l1\n\
+  # %l1 has the GOT. %l3 has _dl_default_scope offset\n\
+  # Now, load _dl_default_scope [2]\n\
+  add   %l3,4,%l3\n\
+  ld    [%l1+%l3],%l4\n\
+  # %l4 has _dl_default_scope [2]\n\
+  # call _dl_init_next until it returns 0, pass _dl_default_scope [2]\n\
+3:\n\
+  call  _dl_init_next\n\
+   mov   %l4,%o0\n\
+  cmp   %o0,%g0\n\
+  bz,a  4f\n\
+   nop\n\
+  call  %o0\n\
+   nop\n\
+  b,a   3b\n\
+4:\n\
+  # Clear the _dl_starting_up variable and pass _dl_fini in %g1 as per ELF ABI.\n\
+  sethi %hi(_dl_starting_up),%l4\n\
+  sethi %hi(_dl_fini),%l3\n\
+  or    %l4,%lo(_dl_starting_up),%l4\n\
+  or    %l3,%lo(_dl_fini),%l3\n\
+  # clear _dl_starting_up\n\
+  ld    [%l1+%l4],%l5\n\
+  st    %g0,[%l5]\n\
+  # load out fini function for atexit in %g1\n\
+  ld    [%l3+%l1],%g1\n\
+  # jump to the user program entry point.\n\
+  jmpl %l0,%g0\n\
   nop\n\
 ");
diff --git a/sysdeps/sparc/elf/Makefile b/sysdeps/sparc/elf/Makefile
new file mode 100644
index 0000000000..319fbdef10
--- /dev/null
+++ b/sysdeps/sparc/elf/Makefile
@@ -0,0 +1,4 @@
+# Sparc/ELF specific definitions.
+
+# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
+ASFLAGS-.so = -fPIC
diff --git a/sysdeps/sparc/elf/start.c b/sysdeps/sparc/elf/start.c
new file mode 100644
index 0000000000..f9c97f89bc
--- /dev/null
+++ b/sysdeps/sparc/elf/start.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+extern char **__environ;
+
+extern void __libc_init_first __P ((int argc, char **argv, char **envp));
+extern int main __P ((int argc, char **argv, char **envp));
+
+register long int sp asm("%sp"), fp asm("%fp");
+
+void
+_start (void)
+{
+  /* It is important that these be declared `register'.
+     Otherwise, when compiled without optimization, they are put on the
+     stack, which loses completely after we zero the FP.  */
+  register int argc;
+  register char **argv, **envp;
+  register long int g1 asm ("%g1");
+  unsigned long int copy_g1 = g1;
+
+  /* Unwind the frame built when we entered the function.  */
+  asm("restore");
+  if (copy_g1)
+    atexit (copy_g1);
+
+  /* And clear the frame pointer.  */
+  fp = 0;
+
+  /* The argument info starts after one register
+     window (64 bytes) past the SP.  */
+  argc = ((int *) sp)[16];
+  argv = (char **) &((int *) sp)[17];
+  envp = &argv[argc + 1];
+  __environ = envp;
+
+  /* Allocate 24 bytes of stack space for the register save area.  */
+  sp -= 24;
+  __libc_init_first (argc, argv, envp);
+#ifdef ELF_INIT_FINI
+  {
+    extern void _fini (void);
+    atexit (_fini);
+    _init ();
+  }
+#endif
+  exit (main (argc, argv, envp));
+}
diff --git a/sysdeps/stub/fcntlbits.h b/sysdeps/stub/fcntlbits.h
index 236520195a..48237f53c6 100644
--- a/sysdeps/stub/fcntlbits.h
+++ b/sysdeps/stub/fcntlbits.h
@@ -1,21 +1,21 @@
 /* O_*, F_*, FD_* bit values for stub configuration.
-Copyright (C) 1991, 1992 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   Copyright (C) 1991, 1992, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 /* These values should be changed as appropriate for your system.  */
 
diff --git a/sysdeps/unix/bsd/bsd4.4/fcntlbits.h b/sysdeps/unix/bsd/bsd4.4/fcntlbits.h
index bb61392569..3ab2bf027d 100644
--- a/sysdeps/unix/bsd/bsd4.4/fcntlbits.h
+++ b/sysdeps/unix/bsd/bsd4.4/fcntlbits.h
@@ -1,21 +1,21 @@
 /* O_*, F_*, FD_* bit values for 4.4 BSD.
-Copyright (C) 1991, 1992 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   Copyright (C) 1991, 1992, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef	_FCNTLBITS_H
 
diff --git a/sysdeps/unix/bsd/fcntlbits.h b/sysdeps/unix/bsd/fcntlbits.h
index dd8b2a9efa..1e87a379e4 100644
--- a/sysdeps/unix/bsd/fcntlbits.h
+++ b/sysdeps/unix/bsd/fcntlbits.h
@@ -1,21 +1,21 @@
 /* O_*, F_*, FD_* bit values for 4.3 BSD.
-Copyright (C) 1991, 1992 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   Copyright (C) 1991, 1992, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef	_FCNTLBITS_H
 
diff --git a/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h b/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h
index 210072222c..a9f66c47a3 100644
--- a/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h
+++ b/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h
@@ -1,21 +1,21 @@
 /* O_*, F_*, FD_* bit values for SunOS 4.
-Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   Copyright (C) 1991, 1992, 1997 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 Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
+   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
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef	_FCNTLBITS_H
 
@@ -33,7 +33,7 @@ Cambridge, MA 02139, USA.  */
 #define	O_EXCL		0x0800	/* Fail if file already exists.  */
 #define	O_TRUNC		0x0400	/* Truncate file to zero length.  */
 #define	O_NOCTTY	0x8000	/* Don't assign a controlling terminal.  */
-#if	defined (__USE_BSD) || defined (__USE_SVID)
+#if defined __USE_BSD || defined __USE_SVID
 #define	O_ASYNC		0x0040	/* Send SIGIO to owner when data is ready.  */
 #define	O_FSYNC		0x2000	/* Synchronous writes.  */
 #define	O_SYNC		O_FSYNC
diff --git a/sysdeps/unix/bsd/ultrix4/fcntlbits.h b/sysdeps/unix/bsd/ultrix4/fcntlbits.h
index bf8e7b2a35..ba736e428e 100644
--- a/sysdeps/unix/bsd/ultrix4/fcntlbits.h
+++ b/sysdeps/unix/bsd/ultrix4/fcntlbits.h
@@ -1,21 +1,21 @@
 /* O_*, F_*, FD_* bit values for Ultrix 4.
-Copyright (C) 1991, 1992 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   Copyright (C) 1991, 1992, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef	_FCNTLBITS_H
 
diff --git a/sysdeps/unix/common/fcntlbits.h b/sysdeps/unix/common/fcntlbits.h
index 0f8443313f..e416e0df13 100644
--- a/sysdeps/unix/common/fcntlbits.h
+++ b/sysdeps/unix/common/fcntlbits.h
@@ -1,21 +1,21 @@
-/* O_*, F_*, FD_* bit values for SVR4 and Irix 4.
-Copyright (C) 1991, 1992, 1995 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+/* O_*, F_*, FD_* bit values for general Unix system.
+   Copyright (C) 1991, 1992, 1995, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef	_FCNTLBITS_H
 
diff --git a/sysdeps/unix/readdir_r.c b/sysdeps/unix/readdir_r.c
index fca3eeeb5f..fa26db6381 100644
--- a/sysdeps/unix/readdir_r.c
+++ b/sysdeps/unix/readdir_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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,13 +33,12 @@ int
 __readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
 {
   struct dirent *dp;
+  size_t reclen;
 
   __libc_lock_lock (dirp->lock);
 
   do
     {
-      size_t reclen;
-
       if (dirp->offset >= dirp->size)
 	{
 	  /* We've emptied out our buffer.  Refill it.  */
@@ -60,6 +59,7 @@ __readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
 	  if (bytes <= 0)
 	    {
 	      dp = NULL;
+	      reclen = 0;
 	      break;
 	    }
 	  dirp->size = (size_t) bytes;
@@ -97,7 +97,7 @@ __readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
 
   if (dp != NULL)
     {
-      *entry = *dp;
+      memcpy (entry, dp, reclen);
       *result = entry;
     }
 
diff --git a/sysdeps/unix/sysv/fcntlbits.h b/sysdeps/unix/sysv/fcntlbits.h
index d04901406a..7f38422707 100644
--- a/sysdeps/unix/sysv/fcntlbits.h
+++ b/sysdeps/unix/sysv/fcntlbits.h
@@ -32,8 +32,9 @@
 #define	O_CREAT		00400	/* Create file if it doesn't exist.  */
 #define	O_EXCL		02000	/* Fail if file already exists.  */
 #define	O_TRUNC		01000	/* Truncate file to zero length.  */
-#if	defined (__USE_BSD) || defined (__USE_SVID)
+#if defined __USE_BSD || defined __USE_SVID
 #define	O_SYNC		00020	/* Synchronous writes.  */
+#define	O_FSYNC		O_SYNC
 #endif
 
 /* File status flags for `open' and `fcntl'.  */
@@ -83,4 +84,13 @@ struct flock
 #define	F_UNLCK	3	/* Remove lock.  */
 
 
+/* Define some more compatibility macros to be backward compatible with
+   BSD systems which did not managed to hide these kernel macros.  */
+#ifdef	__USE_BSD
+#define	FAPPEND		O_APPEND
+#define	FFSYNC		O_FSYNC
+#define	FNONBLOCK	O_NONBLOCK
+#define	FNDELAY		O_NDELAY
+#endif /* Use BSD.  */
+
 #endif	/* fcntlbits.h */
diff --git a/sysdeps/unix/sysv/irix4/fcntlbits.h b/sysdeps/unix/sysv/irix4/fcntlbits.h
index a8bb776cf4..318e483279 100644
--- a/sysdeps/unix/sysv/irix4/fcntlbits.h
+++ b/sysdeps/unix/sysv/irix4/fcntlbits.h
@@ -1,21 +1,21 @@
 /* O_*, F_*, FD_* bit values for SGI Irix 4.
-Copyright (C) 1994 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   Copyright (C) 1994, 1997 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 Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
+   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
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #ifndef	_FCNTLBITS_H
 
@@ -34,6 +34,7 @@ Cambridge, MA 02139, USA.  */
 #define	O_TRUNC		01000	/* Truncate file to zero length.  */
 #ifdef __USE_MISC
 #define	O_SYNC		00020	/* Synchronous writes.  */
+#define	O_FSYNC		O_SYNC
 #define	O_ASYNC		00100	/* Send SIGIO to owner when data is ready.  */
 #endif
 
@@ -95,4 +96,15 @@ struct flock
 #define	F_UNLCK	3	/* Remove lock.  */
 
 
+/* Define some more compatibility macros to be backward compatible with
+   BSD systems which did not managed to hide these kernel macros.  */
+#ifdef	__USE_BSD
+#define	FAPPEND		O_APPEND
+#define	FFSYNC		O_FSYNC
+#define	FASYNC		O_ASYNC
+#define	FNONBLOCK	O_NONBLOCK
+#define	FNDELAY		O_NDELAY
+#endif /* Use BSD.  */
+
+
 #endif	/* fcntlbits.h */
diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist
index 9c41e50b4c..7b94300c6a 100644
--- a/sysdeps/unix/sysv/linux/Dist
+++ b/sysdeps/unix/sysv/linux/Dist
@@ -1,6 +1,7 @@
 cmsg_nxthdr.c
 init-first.h
 kernel_sigaction.h
+kernel_stat.h
 llseek.c
 siglist.h
 sysctl.c
diff --git a/sysdeps/unix/sysv/linux/alpha/Dist b/sysdeps/unix/sysv/linux/alpha/Dist
index 344ffa55fb..80fca49a9b 100644
--- a/sysdeps/unix/sysv/linux/alpha/Dist
+++ b/sysdeps/unix/sysv/linux/alpha/Dist
@@ -4,6 +4,7 @@ ioperm.c
 init-first.h
 clone.S
 kernel_sigaction.h
+kernel_stat.h
 sys/io.h
 sys/acct.h
 sys/kernel_termios.h
diff --git a/sysdeps/unix/sysv/linux/alpha/fcntlbits.h b/sysdeps/unix/sysv/linux/alpha/fcntlbits.h
index e8697d9898..faf198393f 100644
--- a/sysdeps/unix/sysv/linux/alpha/fcntlbits.h
+++ b/sysdeps/unix/sysv/linux/alpha/fcntlbits.h
@@ -23,6 +23,12 @@
 #include <sys/types.h>
 
 
+/* In GNU, read and write are bits (unlike BSD).  */
+#ifdef __USE_GNU
+#define	O_READ		O_RDONLY /* Open for reading.  */
+#define O_WRITE		O_WRONLY /* Open for writing.  */
+#define O_NORW		0	/* Open without R/W access.  */
+#endif
 /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
    located on an ext2 file system */
 #define O_ACCMODE	  0003
@@ -38,7 +44,8 @@
 #define O_APPEND	 00010
 #define O_NDELAY	O_NONBLOCK
 #define O_SYNC		040000
-#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_FSYNC		O_SYNC
+#define O_ASYNC		020000	/* fcntl, for BSD compatibility */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -86,6 +93,7 @@ struct flock
 #ifdef	__USE_BSD
 #define	FAPPEND		O_APPEND
 #define	FFSYNC		O_FSYNC
+#define	FASYNC		O_ASYNC
 #define	FNONBLOCK	O_NONBLOCK
 #define	FNDELAY		O_NDELAY
 #endif /* Use BSD.  */
diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
new file mode 100644
index 0000000000..7109677269
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
@@ -0,0 +1,19 @@
+/* Definition of `struct stat' used in the kernel..  */
+struct kernel_stat
+  {
+    unsigned int st_dev;
+    unsigned int st_ino;
+    unsigned int st_mode;
+    unsigned int st_nlink;
+    unsigned int st_uid;
+    unsigned int st_gid;
+    unsigned int st_rdev;
+    long int st_size;
+    unsigned long int st_atime;
+    unsigned long int st_mtime;
+    unsigned long int st_ctime;
+    unsigned int st_blksize;
+    int st_blocks;
+    unsigned int st_flags;
+    unsigned int st_gen;
+  };
diff --git a/sysdeps/unix/sysv/linux/alpha/statbuf.h b/sysdeps/unix/sysv/linux/alpha/statbuf.h
index 92c9df7404..207fa0ca1c 100644
--- a/sysdeps/unix/sysv/linux/alpha/statbuf.h
+++ b/sysdeps/unix/sysv/linux/alpha/statbuf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997 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,30 +19,30 @@
 #ifndef	_STATBUF_H
 #define	_STATBUF_H	1
 
-/* The Alpha has no additional syscall versions.  */
-
 /* Versions of the `struct stat' data structure.  */
-#define _STAT_VER		0
+#define _STAT_VER_LINUX_OLD	0
+#define _STAT_VER_LINUX		1
+#define _STAT_VER		_STAT_VER_LINUX
 
 /* Versions of the `xmknod' interface.  */
 #define _MKNOD_VER_LINUX	0
 
 struct stat
   {
-    unsigned int st_dev;		/* Device.  */
-    unsigned int st_ino;		/* File serial number.	*/
-    unsigned int st_mode;		/* File mode.  */
-    unsigned int st_nlink;		/* Link count.  */
-    unsigned int st_uid;		/* User ID of the file's owner.	*/
-    unsigned int st_gid;		/* Group ID of the file's group.*/
-    unsigned int st_rdev;		/* Device number, if device.  */
-    long int st_size;			/* Size of file, in bytes.  */
-    unsigned long int st_atime;		/* Time of last access.  */
-    unsigned long int st_mtime;		/* Time of last modification.  */
-    unsigned long int st_ctime;		/* Time of last status change.  */
-    unsigned int st_blksize;		/* Optimal block size for I/O.  */
-#define	_STATBUF_ST_BLKSIZE		/* Tell code we have this member.  */
-    int st_blocks;			/* Nr. of 512-byte blocks allocated.  */
+    __dev_t st_dev;		/* Device.  */
+    __ino_t st_ino;		/* File serial number.	*/
+    __mode_t st_mode;		/* File mode.  */
+    __nlink_t st_nlink;		/* Link count.  */
+    __uid_t st_uid;		/* User ID of the file's owner.	*/
+    __gid_t st_gid;		/* Group ID of the file's group.*/
+    __dev_t st_rdev;		/* Device number, if device.  */
+    __off_t st_size;		/* Size of file, in bytes.  */
+    __time_t st_atime;		/* Time of last access.  */
+    __time_t st_mtime;		/* Time of last modification.  */
+    __time_t st_ctime;		/* Time of last status change.  */
+    unsigned int st_blksize;	/* Optimal block size for I/O.  */
+#define	_STATBUF_ST_BLKSIZE	/* Tell code we have this member.  */
+    int st_blocks;		/* Nr. of 512-byte blocks allocated.  */
     unsigned int st_flags;
     unsigned int st_gen;
   };
diff --git a/sysdeps/unix/sysv/linux/fcntlbits.h b/sysdeps/unix/sysv/linux/fcntlbits.h
index d7e889fc5e..fdc67ce4eb 100644
--- a/sysdeps/unix/sysv/linux/fcntlbits.h
+++ b/sysdeps/unix/sysv/linux/fcntlbits.h
@@ -23,6 +23,12 @@
 #include <sys/types.h>
 
 
+/* In GNU, read and write are bits (unlike BSD).  */
+#ifdef __USE_GNU
+#define	O_READ		O_RDONLY /* Open for reading.  */
+#define O_WRITE		O_WRONLY /* Open for writing.  */
+#define O_NORW		0	/* Open without R/W access.  */
+#endif
 /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
    located on an ext2 file system */
 #define O_ACCMODE	  0003
@@ -37,7 +43,8 @@
 #define O_NONBLOCK	 04000
 #define O_NDELAY	O_NONBLOCK
 #define O_SYNC		010000
-#define FASYNC		020000	/* fcntl, for BSD compatibility */
+#define O_FSYNC		O_SYNC
+#define O_ASYNC		020000
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -85,6 +92,7 @@ struct flock
 #ifdef	__USE_BSD
 #define	FAPPEND		O_APPEND
 #define	FFSYNC		O_FSYNC
+#define	FASYNC		O_ASYNC
 #define	FNONBLOCK	O_NONBLOCK
 #define	FNDELAY		O_NDELAY
 #endif /* Use BSD.  */
diff --git a/sysdeps/unix/sysv/linux/fxstat.c b/sysdeps/unix/sysv/linux/fxstat.c
new file mode 100644
index 0000000000..103218711b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/fxstat.c
@@ -0,0 +1,92 @@
+/* fxstat using old-style Unix fstat system call.
+   Copyright (C) 1991, 1995, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "kernel_stat.h"
+
+extern int __syscall_fstat (int, struct kernel_stat *);
+
+/* Get information about the file descriptor FD in BUF.  */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+  struct kernel_stat kbuf;
+  int result;
+
+  switch (vers)
+    {
+    case _STAT_VER_LINUX_OLD:
+      /* Nothing to do.  The struct is in the form the kernel expects
+	 it to be.  */
+      result = __syscall_fstat (fd, (struct kernel_stat *) buf);
+      break;
+
+    case _STAT_VER_LINUX:
+      /* Do the system call.  */
+      result = __syscall_fstat (fd, &kbuf);
+
+      /* Convert to current kernel version of `struct stat'.  */
+      buf->st_dev = kbuf.st_dev;
+#ifdef _HAVE___PAD1
+      buf->__pad1 = 0;
+#endif
+      buf->st_ino = kbuf.st_ino;
+      buf->st_mode = kbuf.st_mode;
+      buf->st_nlink = kbuf.st_nlink;
+      buf->st_uid = kbuf.st_uid;
+      buf->st_gid = kbuf.st_gid;
+      buf->st_rdev = kbuf.st_rdev;
+#ifdef _HAVE___PAD2
+      buf->__pad2 = 0;
+#endif
+      buf->st_size = kbuf.st_size;
+      buf->st_blksize = kbuf.st_blksize;
+      buf->st_blocks = kbuf.st_blocks;
+      buf->st_atime = kbuf.st_atime;
+#ifdef _HAVE___UNUSED1
+      buf->__unused1 = 0;
+#endif
+      buf->st_mtime = kbuf.st_mtime;
+#ifdef _HAVE___UNUSED2
+      buf->__unused2 = 0;
+#endif
+      buf->st_ctime = kbuf.st_ctime;
+#ifdef _HAVE___UNUSED3
+      buf->__unused3 = 0;
+#endif
+#ifdef _HAVE___UNUSED4
+      buf->__unused4 = 0;
+#endif
+#ifdef _HAVE___UNUSED5
+      buf->__unused5 = 0;
+#endif
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      result = -1;
+      break;
+    }
+
+  return result;
+}
+weak_alias (__fxstat, _fxstat)
diff --git a/sysdeps/unix/sysv/linux/init-first.h b/sysdeps/unix/sysv/linux/init-first.h
index dd4f85af9d..a9df8da52d 100644
--- a/sysdeps/unix/sysv/linux/init-first.h
+++ b/sysdeps/unix/sysv/linux/init-first.h
@@ -1,3 +1,22 @@
+/* Prepare arguments for library initialization function.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
 /* The job of this fragment it to find argc and friends for INIT.
    This is done in one of two ways: either in the stack context
    of program start, or having dlopen pass them in.  */
@@ -7,7 +26,7 @@ void NAME (void *arg)							      \
 {									      \
   int argc;								      \
   char **argv, **envp;							      \
-  /* The next variable is only here to work around a bug in gcc <= 2.7.2.1.   \
+  /* The next variable is only here to work around a bug in gcc <= 2.7.2.2.   \
      If the address would be taken inside the expression the optimizer	      \
      would try to be too smart and throws it away.  Grrr.  */		      \
   int *dummy_addr = &_dl_starting_up;					      \
diff --git a/sysdeps/unix/sysv/linux/kernel_stat.h b/sysdeps/unix/sysv/linux/kernel_stat.h
new file mode 100644
index 0000000000..bd7ddcc9bc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/kernel_stat.h
@@ -0,0 +1,31 @@
+/* Definition of `struct stat' used in the kernel..  */
+struct kernel_stat
+  {
+    unsigned short int st_dev;
+    unsigned short int __pad1;
+#define _HAVE___PAD1
+    unsigned long int st_ino;
+    unsigned short int st_mode;
+    unsigned short int st_nlink;
+    unsigned short int st_uid;
+    unsigned short int st_gid;
+    unsigned short int st_rdev;
+    unsigned short int __pad2;
+#define _HAVE___PAD2
+    unsigned long int st_size;
+    unsigned long int st_blksize;
+    unsigned long int st_blocks;
+    unsigned long int st_atime;
+    unsigned long int __unused1;
+#define _HAVE___UNUSED1
+    unsigned long int st_mtime;
+    unsigned long int __unused2;
+#define _HAVE___UNUSED2
+    unsigned long int st_ctime;
+    unsigned long int __unused3;
+#define _HAVE___UNUSED3
+    unsigned long int __unused4;
+#define _HAVE___UNUSED4
+    unsigned long int __unused5;
+#define _HAVE___UNUSED5
+  };
diff --git a/sysdeps/unix/sysv/linux/lxstat.c b/sysdeps/unix/sysv/linux/lxstat.c
new file mode 100644
index 0000000000..713490cf66
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/lxstat.c
@@ -0,0 +1,92 @@
+/* lxstat using old-style Unix fstat system call.
+   Copyright (C) 1991, 1995, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "kernel_stat.h"
+
+extern int __syscall_lstat (const char *, struct kernel_stat *);
+
+/* Get information about the file NAME in BUF.  */
+int
+__lxstat (int vers, const char *name, struct stat *buf)
+{
+  struct kernel_stat kbuf;
+  int result;
+
+  switch (vers)
+    {
+    case _STAT_VER_LINUX_OLD:
+      /* Nothing to do.  The struct is in the form the kernel expects
+	 it to be.  */
+      result = __syscall_lstat (name, (struct kernel_stat *) buf);
+      break;
+
+    case _STAT_VER_LINUX:
+      /* Do the system call.  */
+      result = __syscall_lstat (name, &kbuf);
+
+      /* Convert to current kernel version of `struct stat'.  */
+      buf->st_dev = kbuf.st_dev;
+#ifdef _HAVE___PAD1
+      buf->__pad1 = 0;
+#endif
+      buf->st_ino = kbuf.st_ino;
+      buf->st_mode = kbuf.st_mode;
+      buf->st_nlink = kbuf.st_nlink;
+      buf->st_uid = kbuf.st_uid;
+      buf->st_gid = kbuf.st_gid;
+      buf->st_rdev = kbuf.st_rdev;
+#ifdef _HAVE___PAD2
+      buf->__pad2 = 0;
+#endif
+      buf->st_size = kbuf.st_size;
+      buf->st_blksize = kbuf.st_blksize;
+      buf->st_blocks = kbuf.st_blocks;
+      buf->st_atime = kbuf.st_atime;
+#ifdef _HAVE___UNUSED1
+      buf->__unused1 = 0;
+#endif
+      buf->st_mtime = kbuf.st_mtime;
+#ifdef _HAVE___UNUSED2
+      buf->__unused2 = 0;
+#endif
+      buf->st_ctime = kbuf.st_ctime;
+#ifdef _HAVE___UNUSED3
+      buf->__unused3 = 0;
+#endif
+#ifdef _HAVE___UNUSED4
+      buf->__unused4 = 0;
+#endif
+#ifdef _HAVE___UNUSED5
+      buf->__unused5 = 0;
+#endif
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      result = -1;
+      break;
+    }
+
+  return result;
+}
+weak_alias (__lxstat, _lxstat)
diff --git a/sysdeps/unix/sysv/linux/net/if_ppp.h b/sysdeps/unix/sysv/linux/net/if_ppp.h
index 27652546ae..567dccebe3 100644
--- a/sysdeps/unix/sysv/linux/net/if_ppp.h
+++ b/sysdeps/unix/sysv/linux/net/if_ppp.h
@@ -1 +1,157 @@
-#include <linux/if_ppp.h>
+/*	From: if_ppp.h,v 1.3 1995/06/12 11:36:50 paulus Exp */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by Carnegie Mellon University.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/*
+ *  ==FILEVERSION 960926==
+ *
+ *  NOTE TO MAINTAINERS:
+ *     If you modify this file at all, please set the above date.
+ *     if_ppp.h is shipped with a PPP distribution as well as with the kernel;
+ *     if everyone increases the FILEVERSION number above, then scripts
+ *     can do the right thing when deciding whether to install a new if_ppp.h
+ *     file.  Don't change the format of that line otherwise, so the
+ *     installation script can recognize it.
+ */
+
+
+#ifndef __NET_IF_PPP_H
+#define __NET_IF_PPP_H 1
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <net/ppp_defs.h>
+
+__BEGIN_DECLS
+
+/*
+ * Packet sizes
+ */
+
+#define	PPP_MTU		1500	/* Default MTU (size of Info field) */
+#define PPP_MAXMRU	65000	/* Largest MRU we allow */
+#define PPP_VERSION	"2.3.0"
+#define PPP_MAGIC	0x5002	/* Magic value for the ppp structure */
+#define PROTO_IPX	0x002b	/* protocol numbers */
+#define PROTO_DNA_RT    0x0027  /* DNA Routing */
+
+
+/*
+ * Bit definitions for flags.
+ */
+
+#define SC_COMP_PROT	0x00000001	/* protocol compression (output) */
+#define SC_COMP_AC	0x00000002	/* header compression (output) */
+#define	SC_COMP_TCP	0x00000004	/* TCP (VJ) compression (output) */
+#define SC_NO_TCP_CCID	0x00000008	/* disable VJ connection-id comp. */
+#define SC_REJ_COMP_AC	0x00000010	/* reject adrs/ctrl comp. on input */
+#define SC_REJ_COMP_TCP	0x00000020	/* reject TCP (VJ) comp. on input */
+#define SC_CCP_OPEN	0x00000040	/* Look at CCP packets */
+#define SC_CCP_UP	0x00000080	/* May send/recv compressed packets */
+#define SC_ENABLE_IP	0x00000100	/* IP packets may be exchanged */
+#define SC_COMP_RUN	0x00001000	/* compressor has been inited */
+#define SC_DECOMP_RUN	0x00002000	/* decompressor has been inited */
+#define SC_DEBUG	0x00010000	/* enable debug messages */
+#define SC_LOG_INPKT	0x00020000	/* log contents of good pkts recvd */
+#define SC_LOG_OUTPKT	0x00040000	/* log contents of pkts sent */
+#define SC_LOG_RAWIN	0x00080000	/* log all chars received */
+#define SC_LOG_FLUSH	0x00100000	/* log all chars flushed */
+#define	SC_MASK		0x0fE0ffff	/* bits that user can change */
+
+/* state bits */
+#define	SC_ESCAPED	0x80000000	/* saw a PPP_ESCAPE */
+#define	SC_FLUSH	0x40000000	/* flush input until next PPP_FLAG */
+#define SC_VJ_RESET	0x20000000	/* Need to reset the VJ decompressor */
+#define SC_XMIT_BUSY	0x10000000	/* ppp_write_wakeup is active */
+#define SC_RCV_ODDP	0x08000000	/* have rcvd char with odd parity */
+#define SC_RCV_EVNP	0x04000000	/* have rcvd char with even parity */
+#define SC_RCV_B7_1	0x02000000	/* have rcvd char with bit 7 = 1 */
+#define SC_RCV_B7_0	0x01000000	/* have rcvd char with bit 7 = 0 */
+#define SC_DC_FERROR	0x00800000	/* fatal decomp error detected */
+#define SC_DC_ERROR	0x00400000	/* non-fatal decomp error detected */
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+    int		protocol;	/* PPP protocol, e.g. PPP_IP */
+    enum NPmode	mode;
+};
+
+/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
+struct ppp_option_data {
+	u_int8_t  *ptr;
+	u_int32_t length;
+	int	  transmit;
+};
+
+struct ifpppstatsreq {
+  struct ifreq	   b;
+  struct ppp_stats stats;			/* statistic information */
+};
+
+struct ifpppcstatsreq {
+  struct ifreq		b;
+  struct ppp_comp_stats stats;
+};
+
+#define ifr__name       b.ifr_ifrn.ifrn_name
+#define stats_ptr       b.ifr_ifru.ifru_data
+
+/*
+ * Ioctl definitions.
+ */
+
+#define	PPPIOCGFLAGS	_IOR('t', 90, int)	/* get configuration flags */
+#define	PPPIOCSFLAGS	_IOW('t', 89, int)	/* set configuration flags */
+#define	PPPIOCGASYNCMAP	_IOR('t', 88, int)	/* get async map */
+#define	PPPIOCSASYNCMAP	_IOW('t', 87, int)	/* set async map */
+#define	PPPIOCGUNIT	_IOR('t', 86, int)	/* get ppp unit number */
+#define	PPPIOCGRASYNCMAP _IOR('t', 85, int)	/* get receive async map */
+#define	PPPIOCSRASYNCMAP _IOW('t', 84, int)	/* set receive async map */
+#define	PPPIOCGMRU	_IOR('t', 83, int)	/* get max receive unit */
+#define	PPPIOCSMRU	_IOW('t', 82, int)	/* set max receive unit */
+#define	PPPIOCSMAXCID	_IOW('t', 81, int)	/* set VJ max slot ID */
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
+#define PPPIOCXFERUNIT	_IO('t', 78)		/* transfer PPP unit */
+#define PPPIOCSCOMPRESS	_IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE	_IOWR('t', 76, struct npioctl) /* get NP mode */
+#define PPPIOCSNPMODE	_IOW('t', 75, struct npioctl)  /* set NP mode */
+#define PPPIOCGDEBUG	_IOR('t', 65, int)	/* Read debug level */
+#define PPPIOCSDEBUG	_IOW('t', 64, int)	/* Set debug level */
+#define PPPIOCGIDLE	_IOR('t', 63, struct ppp_idle) /* get idle time */
+
+#define SIOCGPPPSTATS   (SIOCDEVPRIVATE + 0)
+#define SIOCGPPPVER     (SIOCDEVPRIVATE + 1)  /* NEVER change this!! */
+#define SIOCGPPPCSTATS  (SIOCDEVPRIVATE + 2)
+
+#if !defined(ifr_mtu)
+#define ifr_mtu	ifr_ifru.ifru_metric
+#endif
+
+__END_DECLS
+
+#endif /* net/if_ppp.h */
diff --git a/sysdeps/unix/sysv/linux/net/ppp_defs.h b/sysdeps/unix/sysv/linux/net/ppp_defs.h
index dfd40e1825..5d613e0d0f 100644
--- a/sysdeps/unix/sysv/linux/net/ppp_defs.h
+++ b/sysdeps/unix/sysv/linux/net/ppp_defs.h
@@ -1,8 +1,7 @@
 #ifndef _NET_PPP_DEFS_H
 #define _NET_PPP_DEFS_H 1
 
-#include <sys/types.h>
-typedef u_int32_t __u32;
+#include <asm/types.h>
 #include <linux/ppp_defs.h>
 
 #endif /* net/ppp_defs.h */
diff --git a/sysdeps/unix/sysv/linux/netinet/ip.h b/sysdeps/unix/sysv/linux/netinet/ip.h
index c779db4e87..89c2b1d296 100644
--- a/sysdeps/unix/sysv/linux/netinet/ip.h
+++ b/sysdeps/unix/sysv/linux/netinet/ip.h
@@ -26,62 +26,65 @@
 
 __BEGIN_DECLS
 
-struct timestamp {
-	u_int8_t	len;
-	u_int8_t	ptr;
+struct timestamp
+  {
+    u_int8_t len;
+    u_int8_t ptr;
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u_int8_t	flags:4,
-		overflow:4;
+    u_int8_t flags:4;
+    u_int8_t overflow:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u_int8_t	overflow:4,
-		flags:4;
+    u_int8_t overflow:4;
+    u_int8_t flags:4;
 #else
 #error	"Please fix <bytesex.h>"
-#endif						
-	u_int32_t	data[9];
-};
-
-struct ip_options {
-  u_int32_t	faddr;		/* Saved first hop address */
-  u_int8_t	optlen;
-  u_int8_t srr;
-  u_int8_t rr;
-  u_int8_t ts;
-  u_int8_t is_setbyuser:1,	/* Set by setsockopt?			*/
-                is_data:1,	/* Options in __data, rather than skb	*/
-                is_strictroute:1, /* Strict source route		*/
-                srr_is_hit:1,	/* Packet destination addr was our one	*/
-                is_changed:1,	/* IP checksum more not valid		*/	
-                rr_needaddr:1,	/* Need to record addr of outgoing dev	*/
-                ts_needtime:1,	/* Need to record timestamp		*/
-                ts_needaddr:1;	/* Need to record addr of outgoing dev  */
-  u_int8_t router_alert;
-  u_int8_t __pad1;
-  u_int8_t __pad2;
-  u_int8_t __data[0];
-};
-
-struct iphdr {
+#endif
+    u_int32_t data[9];
+  };
+
+struct ip_options
+  {
+    u_int32_t faddr;		/* Saved first hop address */
+    u_int8_t optlen;
+    u_int8_t srr;
+    u_int8_t rr;
+    u_int8_t ts;
+    u_int8_t is_setbyuser:1;	/* Set by setsockopt?			*/
+    u_int8_t is_data:1;		/* Options in __data, rather than skb	*/
+    u_int8_t is_strictroute:1; /* Strict source route		*/
+    u_int8_t srr_is_hit:1;	/* Packet destination addr was our one	*/
+    u_int8_t is_changed:1;	/* IP checksum more not valid		*/
+    u_int8_t rr_needaddr:1;	/* Need to record addr of outgoing dev	*/
+    u_int8_t ts_needtime:1;	/* Need to record timestamp		*/
+    u_int8_t ts_needaddr:1;	/* Need to record addr of outgoing dev  */
+    u_int8_t router_alert;
+    u_int8_t __pad1;
+    u_int8_t __pad2;
+    u_int8_t __data[0];
+  };
+
+struct iphdr
+  {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u_int8_t	ihl:4,
-		version:4;
+    u_int8_t ihl:4;
+    u_int8_t version:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u_int8_t	version:4,
-  		ihl:4;
+    u_int8_t	version:4;
+    u_int8_t ihl:4;
 #else
 #error	"Please fix <bytesex.h>"
 #endif
-	u_int8_t	tos;
-	u_int16_t	tot_len;
-	u_int16_t	id;
-	u_int16_t	frag_off;
-	u_int8_t	ttl;
-	u_int8_t	protocol;
-	u_int16_t	check;
-	u_int32_t	saddr;
-	u_int32_t	daddr;
-	/*The options start here. */
-};
+    u_int8_t tos;
+    u_int16_t tot_len;
+    u_int16_t id;
+    u_int16_t frag_off;
+    u_int8_t ttl;
+    u_int8_t protocol;
+    u_int16_t check;
+    u_int32_t saddr;
+    u_int32_t daddr;
+    /*The options start here. */
+  };
 
 #ifdef __USE_BSD
 /*
@@ -127,46 +130,48 @@ struct iphdr {
 /*
  * Structure of an internet header, naked of options.
  */
-struct ip {
+struct ip
+  {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u_int8_t  ip_hl:4,		/* header length */
-		  ip_v:4;		/* version */
+    u_int8_t ip_hl:4;			/* header length */
+    u_int8_t ip_v:4;			/* version */
 #endif
 #if __BYTE_ORDER == __BIG_ENDIAN
-	u_int8_t  ip_v:4,		/* version */
-		  ip_hl:4;		/* header length */
+    u_int8_t ip_v:4;			/* version */
+    u_int8_t ip_hl:4;			/* header length */
 #endif
-	u_int8_t  ip_tos;		/* type of service */
-	u_short ip_len;		/* total length */
-	u_short ip_id;		/* identification */
-	u_short ip_off;		/* fragment offset field */
+    u_int8_t ip_tos;			/* type of service */
+    u_short ip_len;			/* total length */
+    u_short ip_id;			/* identification */
+    u_short ip_off;			/* fragment offset field */
 #define	IP_RF 0x8000			/* reserved fragment flag */
 #define	IP_DF 0x4000			/* dont fragment flag */
 #define	IP_MF 0x2000			/* more fragments flag */
 #define	IP_OFFMASK 0x1fff		/* mask for fragmenting bits */
-	u_int8_t  ip_ttl;		/* time to live */
-	u_int8_t  ip_p;			/* protocol */
-	u_short ip_sum;		/* checksum */
-	struct	  in_addr ip_src, ip_dst; /* source and dest address */
-};
+    u_int8_t ip_ttl;			/* time to live */
+    u_int8_t ip_p;			/* protocol */
+    u_short ip_sum;			/* checksum */
+    struct in_addr ip_src, ip_dst;	/* source and dest address */
+  };
 
 /*
  * Time stamp option structure.
  */
-struct	ip_timestamp {
-	u_int8_t ipt_code;		/* IPOPT_TS */
-	u_int8_t ipt_len;		/* size of structure (variable) */
-	u_int8_t ipt_ptr;		/* index of current entry */
+struct ip_timestamp
+  {
+    u_int8_t ipt_code;			/* IPOPT_TS */
+    u_int8_t ipt_len;			/* size of structure (variable) */
+    u_int8_t ipt_ptr;			/* index of current entry */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u_int8_t ipt_flg:4,		/* flags, see below */
-		 ipt_oflw:4;		/* overflow counter */
+    u_int8_t ipt_flg:4,			/* flags, see below */
+    u_int8_t ipt_oflw:4;		/* overflow counter */
 #endif
 #if __BYTE_ORDER == __BIG_ENDIAN
-	u_int8_t ipt_oflw:4,		/* overflow counter */
-		 ipt_flg:4;		/* flags, see below */
+    u_int8_t ipt_oflw:4,		/* overflow counter */
+    u_int8_t ipt_flg:4;			/* flags, see below */
 #endif
-	u_int32_t data[9];
-};
+    u_int32_t data[9];
+  };
 #endif /* __USE_BSD */
 
 #define	IPVERSION	4               /* IP version number */
@@ -175,6 +180,8 @@ struct	ip_timestamp {
 /*
  * Definitions for IP type of service (ip_tos)
  */
+#define	IPTOS_TOS_MASK		0x1E
+#define	IPTOS_TOS(tos)		((tos) & IPTOS_TOS_MASK)
 #define	IPTOS_LOWDELAY		0x10
 #define	IPTOS_THROUGHPUT	0x08
 #define	IPTOS_RELIABILITY	0x04
@@ -184,6 +191,8 @@ struct	ip_timestamp {
 /*
  * Definitions for IP precedence (also in ip_tos) (hopefully unused)
  */
+#define	IPTOS_PREC_MASK			0xe0
+#define	IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
 #define	IPTOS_PREC_NETCONTROL		0xe0
 #define	IPTOS_PREC_INTERNETCONTROL	0xc0
 #define	IPTOS_PREC_CRITIC_ECP		0xa0
@@ -196,24 +205,35 @@ struct	ip_timestamp {
 /*
  * Definitions for options.
  */
-#define	IPOPT_COPIED(o)		((o)&0x80)
-#define	IPOPT_CLASS(o)		((o)&0x60)
-#define	IPOPT_NUMBER(o)		((o)&0x1f)
+#define	IPOPT_COPY		0x80
+#define	IPOPT_CLASS_MASK	0x60
+#define	IPOPT_NUMBER_MASK	0x1f
+
+#define	IPOPT_COPIED(o)		((o) & IPOPT_COPY)
+#define	IPOPT_CLASS(o)		((o) & IPOPT_CLASS_MASK)
+#define	IPOPT_NUMBER(o)		((o) & IPOPT_NUMBER_MASK)
 
 #define	IPOPT_CONTROL		0x00
 #define	IPOPT_RESERVED1		0x20
 #define	IPOPT_DEBMEAS		0x40
+#define	IPOPT_MEASUREMENT       IPOPT_DEBMEAS
 #define	IPOPT_RESERVED2		0x60
 
 #define	IPOPT_EOL		0		/* end of option list */
+#define	IPOPT_END		IPOPT_EOL
 #define	IPOPT_NOP		1		/* no operation */
+#define	IPOPT_NOOP		IP_NOP
 
 #define	IPOPT_RR		7		/* record packet route */
 #define	IPOPT_TS		68		/* timestamp */
+#define	IPOPT_TIMESTAMP		IPOPT_TS
 #define	IPOPT_SECURITY		130		/* provide s,c,h,tcc */
+#define	IPOPT_SEC		IPOPT_SECURITY
 #define	IPOPT_LSRR		131		/* loose source route */
 #define	IPOPT_SATID		136		/* satnet id */
+#define	IPOPT_SID		IPOPT_SATID
 #define	IPOPT_SSRR		137		/* strict source route */
+#define	IPOPT_RA		148		/* router alert */
 
 /*
  * Offsets to fields in options other than EOL and NOP.
diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c
index 13bcb0459b..8f079bf444 100644
--- a/sysdeps/unix/sysv/linux/sparc/brk.c
+++ b/sysdeps/unix/sysv/linux/sparc/brk.c
@@ -40,7 +40,7 @@ __brk (void *addr)
        "t 0x10\n\t"
        "mov %%o0, %0\n\t"
        : "=r" (newbrk)
-       : "0" (SYS_brk), "r" (addr)
+       : "0" (__NR_brk), "r" (addr)
        : "g1", "o0");
 
   __curbrk = newbrk;
diff --git a/sysdeps/unix/sysv/linux/statbuf.h b/sysdeps/unix/sysv/linux/statbuf.h
index 39bbdc9ece..15ffe637bc 100644
--- a/sysdeps/unix/sysv/linux/statbuf.h
+++ b/sysdeps/unix/sysv/linux/statbuf.h
@@ -20,8 +20,9 @@
 #define	_STATBUF_H	1
 
 /* Versions of the `struct stat' data structure.  */
-#define _STAT_VER_LINUX		1
+#define _STAT_VER_LINUX_OLD	1
 #define _STAT_VER_SVR4		2
+#define _STAT_VER_LINUX		3
 #define _STAT_VER		_STAT_VER_LINUX	/* The one defined below.  */
 
 /* Versions of the `xmknod' interface.  */
@@ -32,25 +33,25 @@
 
 struct stat
   {
-    unsigned short int st_dev;		/* Device.  */
+    __dev_t st_dev;			/* Device.  */
     unsigned short int __pad1;
-    unsigned long int st_ino;		/* File serial number.	*/
-    unsigned short int st_mode;		/* File mode.  */
-    unsigned short int st_nlink;	/* Link count.  */
-    unsigned short int st_uid;		/* User ID of the file's owner.	*/
-    unsigned short int st_gid;		/* Group ID of the file's group.*/
-    unsigned short int st_rdev;		/* Device number, if device.  */
+    __ino_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
     unsigned short int __pad2;
-    long int st_size;			/* Size of file, in bytes.  */
+    __off_t st_size;			/* Size of file, in bytes.  */
     unsigned long int st_blksize;	/* Optimal block size for I/O.  */
 #define	_STATBUF_ST_BLKSIZE		/* Tell code we have this member.  */
 
     unsigned long int st_blocks;	/* Number of 512-byte blocks allocated.  */
-    long int st_atime;			/* Time of last access.  */
+    __time_t st_atime;			/* Time of last access.  */
     unsigned long int __unused1;
-    long int st_mtime;			/* Time of last modification.  */
+    __time_t st_mtime;			/* Time of last modification.  */
     unsigned long int __unused2;
-    long int st_ctime;			/* Time of last status change.  */
+    __time_t st_ctime;			/* Time of last status change.  */
     unsigned long int __unused3;
     unsigned long int __unused4;
     unsigned long int __unused5;
diff --git a/sysdeps/unix/sysv/linux/xstat.c b/sysdeps/unix/sysv/linux/xstat.c
new file mode 100644
index 0000000000..be49b9d1de
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/xstat.c
@@ -0,0 +1,92 @@
+/* xstat using old-style Unix fstat system call.
+   Copyright (C) 1991, 1995, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "kernel_stat.h"
+
+extern int __syscall_stat (const char *, struct kernel_stat *);
+
+/* Get information about the file NAME in BUF.  */
+int
+__xstat (int vers, const char *name, struct stat *buf)
+{
+  struct kernel_stat kbuf;
+  int result;
+
+  switch (vers)
+    {
+    case _STAT_VER_LINUX_OLD:
+      /* Nothing to do.  The struct is in the form the kernel expects
+	 it to be.  */
+      result = __syscall_stat (name, (struct kernel_stat *) buf);
+      break;
+
+    case _STAT_VER_LINUX:
+      /* Do the system call.  */
+      result = __syscall_stat (name, &kbuf);
+
+      /* Convert to current kernel version of `struct stat'.  */
+      buf->st_dev = kbuf.st_dev;
+#ifdef _HAVE___PAD1
+      buf->__pad1 = 0;
+#endif
+      buf->st_ino = kbuf.st_ino;
+      buf->st_mode = kbuf.st_mode;
+      buf->st_nlink = kbuf.st_nlink;
+      buf->st_uid = kbuf.st_uid;
+      buf->st_gid = kbuf.st_gid;
+      buf->st_rdev = kbuf.st_rdev;
+#ifdef _HAVE___PAD2
+      buf->__pad2 = 0;
+#endif
+      buf->st_size = kbuf.st_size;
+      buf->st_blksize = kbuf.st_blksize;
+      buf->st_blocks = kbuf.st_blocks;
+      buf->st_atime = kbuf.st_atime;
+#ifdef _HAVE___UNUSED1
+      buf->__unused1 = 0;
+#endif
+      buf->st_mtime = kbuf.st_mtime;
+#ifdef _HAVE___UNUSED2
+      buf->__unused2 = 0;
+#endif
+      buf->st_ctime = kbuf.st_ctime;
+#ifdef _HAVE___UNUSED3
+      buf->__unused3 = 0;
+#endif
+#ifdef _HAVE___UNUSED4
+      buf->__unused4 = 0;
+#endif
+#ifdef _HAVE___UNUSED5
+      buf->__unused5 = 0;
+#endif
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      result = -1;
+      break;
+    }
+
+  return result;
+}
+weak_alias (__xstat, _xstat)
diff --git a/time/Makefile b/time/Makefile
index cf0ac6a89d..1d8490cc8b 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -35,7 +35,7 @@ routines	:= offtime asctime clock ctime ctime_r difftime	\
 		   strptime
 
 others	:= ap zdump zic
-tests	:= test_time clocktest
+tests	:= test_time clocktest test-tz
 
 tzbases := africa antarctica asia australasia europe northamerica \
 	   southamerica etcetera factory systemv \
@@ -54,15 +54,6 @@ all: # Make this the default target; it will be defined in Rules.
 
 include ../Makeconfig	# Get objpfx defined so we can use it below.
 
-ifeq (no,$(cross-compiling))
-# We can run the test-tz test only if we can install the test data using
-# zic.  This isn't possible when cross-compiling.
-tests += test-tz
-
-# Before the test-tz test can be run we need the data to be installed.
-tests: install-test-data
-endif
-
 # z.* use this variable.
 define nl
 
@@ -71,7 +62,7 @@ endef
 -include $(addprefix $(objpfx)z.,$(tzfiles))
 
 # Make these absolute file names.
-installed-localtime-file := $(firstword $(filter /%,$(localtime-file)) \
+installed-localtime-file := $(firstword $(filter /%,$(inst_localtime-file)) \
 					$(addprefix $(inst_zonedir)/, \
 						    $(localtime-file)))
 installed-posixrules-file := $(firstword $(filter /%,$(posixrules-file)) \
@@ -178,17 +169,17 @@ CFLAGS-tzfile.c = $(tz-cflags)
 CFLAGS-tzset.c = $(tz-cflags)
 
 # We have to make sure the data for testing the tz functions is available.
-.PHONY: install-test-data
-install-test-data: $(addprefx $(objpfx)testdata/, America/New_York \
-						  Etc/UTC UTC)
+$(objpfx)test-tz.out: $(addprefix $(objpfx)testdata/, America/New_York \
+						      Etc/UTC UTC)
 
-$(objpfx)testdata/America/New_York: $(objpfx)zic $(leapseconds) yearistype
+$(objpfx)testdata/America/New_York: northamerica $(objpfx)zic \
+				    $(leapseconds) yearistype
 	$(built-program-cmd) -d $(objpfx)testdata -L $(leapseconds) \
 	  -y yearistype northamerica
-$(objpfx)testdata/Etc/UTC: $(objpfx)zic $(leapseconds) yearistype
+$(objpfx)testdata/Etc/UTC: etcetera $(objpfx)zic $(leapseconds) yearistype
 	$(built-program-cmd) -d $(objpfx)testdata -L $(leapseconds) \
 	  -y yearistype etcetera
-$(objpfx)testdata/UTC: $(objpfx)testdata/Etc/UTC $(objpfx)zic	\
+$(objpfx)testdata/UTC: simplebackw $(objpfx)zic $(objpfx)testdata/Etc/UTC \
 		       $(leapseconds) yearistype
 	$(built-program-cmd) -d $(objpfx)testdata -L $(leapseconds) \
 	  -y yearistype simplebackw
diff --git a/time/mktime.c b/time/mktime.c
index d8fdf3a6c6..30438b5b10 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -74,8 +74,10 @@
 #endif
 
 #ifndef TIME_T_MIN
-#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \
-		    : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
+/* The outer cast to time_t works around a bug in Cray C 5.0.3.0.  */
+#define TIME_T_MIN ((time_t) \
+		    (0 < (time_t) -1 ? (time_t) 0 \
+		     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
 #endif
 #ifndef TIME_T_MAX
 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
diff --git a/time/strptime.c b/time/strptime.c
index 3340b4317c..89cfa8e2a4 100644
--- a/time/strptime.c
+++ b/time/strptime.c
@@ -129,7 +129,7 @@ localtime_r (t, tp)
 #endif
 #define recursive(new_fmt) \
   (*(new_fmt) != '\0'							      \
-   && strptime_internal (rp, (new_fmt), tm, decided) != NULL)
+   && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
 
 
 #ifdef _LIBC
@@ -239,27 +239,27 @@ strptime_internal (buf, format, tm, decided)
 #ifdef _NL_CURRENT
 	      if (*decided !=raw)
 		{
-		  if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
+		  if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
 		    {
 		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
-				     ab_weekday_name[cnt]))
+			  && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
+				     weekday_name[cnt]))
 			*decided = loc;
 		      break;
 		    }
-		  if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
+		  if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
 		    {
 		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
-				     weekday_name[cnt]))
+			  && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
+				     ab_weekday_name[cnt]))
 			*decided = loc;
 		      break;
 		    }
 		}
 #endif
 	      if (*decided != loc
-		  && (match_string (ab_weekday_name[cnt], rp)
-		      || match_string (weekday_name[cnt], rp)))
+		  && (match_string (weekday_name[cnt], rp)
+		      || match_string (ab_weekday_name[cnt], rp)))
 		{
 		  *decided = raw;
 		  break;
@@ -279,26 +279,26 @@ strptime_internal (buf, format, tm, decided)
 #ifdef _NL_CURRENT
 	      if (*decided !=raw)
 		{
-		  if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
+		  if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
 		    {
 		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
-				     ab_month_name[cnt]))
+			  && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
+				     month_name[cnt]))
 			*decided = loc;
 		      break;
 		    }
-		  if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
+		  if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
 		    {
 		      if (*decided == not
-			  && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
-				     month_name[cnt]))
+			  && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
+				     ab_month_name[cnt]))
 			*decided = loc;
 		      break;
 		    }
 		}
 #endif
-	      if (match_string (ab_month_name[cnt], rp)
-		  || match_string (month_name[cnt], rp))
+	      if (match_string (month_name[cnt], rp)
+		  || match_string (ab_month_name[cnt], rp))
 		{
 		  *decided = raw;
 		  break;
@@ -542,7 +542,7 @@ strptime_internal (buf, format, tm, decided)
 	case 'Y':
 	  /* Match year including century number.  */
 	  get_number (0, INT_MAX);
-	  tm->tm_year = val - (val >= 2000 ? 2000 : 1900);
+	  tm->tm_year = val - 1900;
 	  break;
 	case 'Z':
 	  /* XXX How to handle this?  */