summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-03-29 17:32:35 +0000
committerUlrich Drepper <drepper@redhat.com>1997-03-29 17:32:35 +0000
commit993b3242cdc37152fbbc7fbd5ce22b2734b04b23 (patch)
treed3c4fc94e027728055d96a370d034b6fb685cf85 /sysdeps
parente7fd8a39abd3a9c9d2139e686b17efb5dc3bf444 (diff)
downloadglibc-993b3242cdc37152fbbc7fbd5ce22b2734b04b23.tar.gz
glibc-993b3242cdc37152fbbc7fbd5ce22b2734b04b23.tar.xz
glibc-993b3242cdc37152fbbc7fbd5ce22b2734b04b23.zip
Update.
1997-03-29 17:39  Ulrich Drepper  <drepper@cygnus.com>

	* math/Makefile (routines): Add carg, s_ccosh and s_csinh.

	* math/complex.h: Add C++ protection.

	* math/libm-test.c (cexp_test): Correct a few bugs.
	(csinh_test): New function.
	(ccosh_test): New function.
	(cacos_test): New function.
	(cacosh_test): New function.
	(casinh_test): New function.
	(catanh_test): New function.
	(main): Add calls to csinh_test and ccosh_test.

	* misc/Makefile (tests): Add tst-tsearch.
	Add rule to link tst-tsearch against libm.
	* misc/tsearch.c: Rewritten to use Red-Black-Tree algorithm by
	Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>.
	* misc/tst-tsearch.c: New file.

	* stdio-common/bug5.c: Clear LD_LIBRARY_PATH environment variable
	before using system.
	* stdio-common/test-popen.c: Clear LD_LIBRARY_PATH environment variable
	before using popen.

	* sysdeps/libm-ieee754/s_cexp.c: Correct handling of special cases.
	* sysdeps/libm-ieee754/s_cexpf.c: Likewise.
	* sysdeps/libm-ieee754/s_cexpl.c: Likewise.

	* sysdeps/libm-i387/s_cexp.S: New file.  ix87 specific implementation
	of complex exponential function.
	* sysdeps/libm-i387/s_cexpf.S: New file.
	* sysdeps/libm-i387/s_cexpl.S: New file.

	* sysdeps/libm-ieee754/s_ccosh.c: New file.  Implementation of
	complex cosh function.
	* sysdeps/libm-ieee754/s_ccoshf.c: New file.
	* sysdeps/libm-ieee754/s_ccoshl.c: New file.
	* sysdeps/libm-ieee754/s_csinh.c: New file.  Implementation of
	complex sinh function.
	* sysdeps/libm-ieee754/s_csinhf.c: New file.
	* sysdeps/libm-ieee754/s_csinhl.c: New file.

	* math/carg.c: New file.  Generic implementatio of carg function.
	* math/cargf.c: New file.
	* math/cargl.c: New file.

1997-03-29 16:07  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/posix/system.c: Update copyright.

1997-03-29 04:18  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-error.c (_dl_catch_error): Add another argument which is
	passed to OPERATE.
	(_dl_receive_error): Likewise.
	* elf/link.h: Change prototypes for _dl_catch_error and
	_dl_receive_error to reflect above change.
	* elf/dl-deps.c: Don't use nested function.  Call _dl_catch_error
	with additional argument with pointer to data.
	* elf/dlclose.c: Likewise.
	* elf/dlerror.c: Likewise.
	* elf/dlopen.c: Likewise.
	* elf/dlsym.c: Likewise.
	* elf/dlvsym.c: Likewise.
	* elf/rtld.c: Likewise.
	* nss/nsswitch.c: Likewise.
	Patch by Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>.

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

	* elf/dl-error.c: Manually set up the values of "c", this avoids a
	call to memcpy and a zero 152 bytes structure.

	* sysdeps/sparc/dl-machine.h (elf_machine_rela): Test
	RTLD_BOOTSTRAP to avoid performing relative relocs on a second
	pass.

	* sysdeps/sparc/udiv_qrnnd.S: Make the code PIC aware.

	* sysdeps/unix/sysv/linux/sparc/Dist: Add kernel_stat.h and
	kernel_sigaction.h

	Add Linux/SPARC specific definitions.
	* sysdeps/unix/sysv/linux/sparc/fcntlbits.h: New file.
	* sysdeps/unix/sysv/linux/sparc/ioctls.h: New file.
	* sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h: New file.
	* sysdeps/unix/sysv/linux/sparc/kernel_stat.h: New file.
	* sysdeps/unix/sysv/linux/sparc/sigaction.h: New file.
	* sysdeps/unix/sysv/linux/sparc/signum.h: New file.
	* sysdeps/unix/sysv/linux/sparc/termbits.h: New file.

1997-03-28 13:06  Philip Blundell  <pjb27@cam.ac.uk>

	* sysdeps/posix/getaddrinfo.c (gaih_inet_serv): Use
	__getservbyname_r() not getservbyname().
	(BROKEN_LIKE_POSIX): Define to 1 so we get strict POSIX behaviour.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/libm-i387/s_cexp.S248
-rw-r--r--sysdeps/libm-i387/s_cexpf.S245
-rw-r--r--sysdeps/libm-i387/s_cexpl.S249
-rw-r--r--sysdeps/libm-ieee754/s_ccosh.c95
-rw-r--r--sysdeps/libm-ieee754/s_ccoshf.c93
-rw-r--r--sysdeps/libm-ieee754/s_ccoshl.c93
-rw-r--r--sysdeps/libm-ieee754/s_cexp.c45
-rw-r--r--sysdeps/libm-ieee754/s_cexpf.c32
-rw-r--r--sysdeps/libm-ieee754/s_cexpl.c32
-rw-r--r--sysdeps/libm-ieee754/s_csinh.c102
-rw-r--r--sysdeps/libm-ieee754/s_csinhf.c100
-rw-r--r--sysdeps/libm-ieee754/s_csinhl.c100
-rw-r--r--sysdeps/posix/getaddrinfo.c29
-rw-r--r--sysdeps/posix/system.c34
-rw-r--r--sysdeps/sparc/dl-machine.h7
-rw-r--r--sysdeps/sparc/udiv_qrnnd.S27
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Dist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/fcntlbits.h96
-rw-r--r--sysdeps/unix/sysv/linux/sparc/ioctls.h39
-rw-r--r--sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h12
-rw-r--r--sysdeps/unix/sysv/linux/sparc/kernel_stat.h21
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sigaction.h52
-rw-r--r--sysdeps/unix/sysv/linux/sparc/signum.h72
-rw-r--r--sysdeps/unix/sysv/linux/sparc/termbits.h217
24 files changed, 1982 insertions, 60 deletions
diff --git a/sysdeps/libm-i387/s_cexp.S b/sysdeps/libm-i387/s_cexp.S
new file mode 100644
index 0000000000..48e002b2f6
--- /dev/null
+++ b/sysdeps/libm-i387/s_cexp.S
@@ -0,0 +1,248 @@
+/* ix87 specific implementation of complex exponential function for double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <sysdep.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
+huge_nan_null_null:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	.double	0.0
+	.double	0.0
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	.double 0.0
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	ASM_SIZE_DIRECTIVE(huge_nan_null_null)
+
+	ASM_TYPE_DIRECTIVE(twopi,@object)
+twopi:
+	.byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
+	.byte 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(twopi)
+
+	ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:
+	.byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
+	.byte 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(l2e)
+
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+
+
+#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(__cexp)
+	fldl	8(%esp)			/* x */
+	fxam
+	fnstsw
+	fldl	16(%esp)		/* y : x */
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	movb	%ah, %dh
+	andb	$0x45, %ah
+	cmpb	$0x05, %ah
+	je	1f			/* Jump if real part is +-Inf */
+	cmpb	$0x01, %ah
+	je	2f			/* Jump if real part is NaN */
+
+	fxam				/* y : x */
+	fnstsw
+	/* If the imaginary part is not finite we return NaN+i NaN, as
+	   for the case when the real part is NaN.  A test for +-Inf and
+	   NaN would be necessary.  But since we know the stack register
+	   we applied `fxam' to is not empty we can simply use one test.
+	   Check your FPU manual for more information.  */
+	andb	$0x01, %ah
+	cmpb	$0x01, %ah
+	je	2f
+
+	/* We have finite numbers in the real and imaginary part.  Do
+	   the real work now.  */
+	fxch			/* x : y */
+	fldt	MO(l2e)		/* log2(e) : x : y */
+	fmulp			/* x * log2(e) : y */
+	fld	%st		/* x * log2(e) : x * log2(e) : y */
+	frndint			/* int(x * log2(e)) : x * log2(e) : y */
+	fsubr	%st, %st(1)	/* int(x * log2(e)) : frac(x * log2(e)) : y */
+	fxch			/* frac(x * log2(e)) : int(x * log2(e)) : y */
+	f2xm1			/* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
+	faddl	MO(one)		/* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
+	fscale			/* e^x : int(x * log2(e)) : y */
+	fst	%st(1)		/* e^x : e^x : y */
+	fxch	%st(2)		/* y : e^x : e^x */
+	fsincos			/* cos(y) : sin(y) : e^x : e^x */
+	fnstsw
+	testl	$0x400, %eax
+	jnz	7f
+	fmulp	%st, %st(3)	/* sin(y) : e^x : e^x * cos(y) */
+	fmulp	%st, %st(1)	/* e^x * sin(y) : e^x * cos(y) */
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fstpl	8(%eax)
+	fstpl	(%eax)
+	ret	$4
+
+	/* We have to reduce the argument to fsincos.  */
+	.align ALIGNARG(4)
+7:	fldt	MO(twopi)	/* 2*pi : y : e^x : e^x */
+	fxch			/* y : 2*pi : e^x : e^x */
+8:	fprem1			/* y%(2*pi) : 2*pi : e^x : e^x */
+	fnstsw
+	testl	$0x400, %eax
+	jnz	8b
+	fstp	%st(1)		/* y%(2*pi) : e^x : e^x */
+	fsincos			/* cos(y) : sin(y) : e^x : e^x */
+	fmulp	%st, %st(3)
+	fmulp	%st, %st(1)
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fstpl	8(%eax)
+	fstpl	(%eax)
+	ret	$4
+
+	/* The real part is +-inf.  We must make further differences.  */
+	.align ALIGNARG(4)
+1:	fxam			/* y : x */
+	fnstsw
+	movb	%ah, %dl
+	andb	$0x01, %ah	/* See above why 0x01 is usable here.  */
+	cmpb	$0x01, %ah
+	je	3f
+
+
+	/* The real part is +-Inf and the imaginary part is finite.  */
+	andl	$0x245, %edx
+	cmpb	$0x40, %dl	/* Imaginary part == 0?  */
+	je	4f		/* Yes ->  */
+
+	fxch			/* x : y */
+	shrl	$5, %edx
+	fstp	%st(0)		/* y */ /* Drop the real part.  */
+	andl	$16, %edx	/* This puts the sign bit of the real part
+				   in bit 4.  So we can use it to index a
+				   small array to select 0 or Inf.  */
+	fsincos			/* cos(y) : sin(y) */
+	fnstsw
+	testl	$0x0400, %eax
+	jnz	5f
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	movl	4(%esp), %edx		/* Pointer to memory for result.  */
+	fstl	8(%edx)
+	fstpl	(%edx)
+	ftst
+	fnstsw
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	%eax, 4(%edx)
+	fstp	%st(0)
+	ftst
+	fnstsw
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	%eax, 12(%edx)
+	fstp	%st(0)
+	ret	$4
+	/* We must reduce the argument to fsincos.  */
+	.align ALIGNARG(4)
+5:	fldt	MO(twopi)
+	fxch
+6:	fprem1
+	fnstsw
+	testl	$0x400, %eax
+	jnz	6b
+	fstp	%st(1)
+	fsincos
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	movl	4(%esp), %edx		/* Pointer to memory for result.  */
+	fstl	8(%edx)
+	fstpl	(%edx)
+	ftst
+	fnstsw
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	%eax, 4(%edx)
+	fstp	%st(0)
+	ftst
+	fnstsw
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	%eax, 12(%edx)
+	fstp	%st(0)
+	ret	$4
+
+	/* The real part is +-Inf and the imaginary part is +-0.  So return
+	   +-Inf+-0i.  */
+	.align ALIGNARG(4)
+4:	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fstpl	8(%eax)
+	shrl	$5, %edx
+	fstp	%st(0)
+	andl	$16, %edx
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	fstpl	(%eax)
+	ret	$4
+
+	/* The real part is +-Inf, the imaginary is also is not finite.  */
+	.align ALIGNARG(4)
+3:	fstp	%st(0)
+	fstp	%st(0)		/* <empty> */
+	movl	%edx, %eax
+	shrl	$5, %edx
+	shll	$4, %eax
+	andl	$16, %edx
+	andl	$32, %eax
+	orl	%eax, %edx
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	fldl	MOX(huge_nan_null_null+8,%edx,1)
+	fstpl	8(%eax)
+	fstpl	(%eax)
+	ret	$4
+
+	/* The real part is NaN.  */
+	.align ALIGNARG(4)
+2:	fstp	%st(0)
+	fstp	%st(0)
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fldl	MO(huge_nan_null_null+8)
+	fstl	(%eax)
+	fstpl	8(%eax)
+	ret	$4
+
+END(__cexp)
+weak_alias (__cexp, cexp)
diff --git a/sysdeps/libm-i387/s_cexpf.S b/sysdeps/libm-i387/s_cexpf.S
new file mode 100644
index 0000000000..6fd414b045
--- /dev/null
+++ b/sysdeps/libm-i387/s_cexpf.S
@@ -0,0 +1,245 @@
+/* ix87 specific implementation of complex exponential function for double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <sysdep.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
+huge_nan_null_null:
+	.byte 0, 0, 0x80, 0x7f
+	.byte 0, 0, 0xc0, 0x7f
+	.float	0.0
+	.float	0.0
+	.byte 0, 0, 0x80, 0x7f
+	.byte 0, 0, 0xc0, 0x7f
+	.float 0.0
+	.byte 0, 0, 0, 0x80
+	ASM_SIZE_DIRECTIVE(huge_nan_null_null)
+
+	ASM_TYPE_DIRECTIVE(twopi,@object)
+twopi:
+	.byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
+	.byte 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(twopi)
+
+	ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:
+	.byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
+	.byte 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(l2e)
+
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+
+
+#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(__cexpf)
+	flds	4(%esp)			/* x */
+	fxam
+	fnstsw
+	flds	8(%esp)			/* y : x */
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	movb	%ah, %dh
+	andb	$0x45, %ah
+	cmpb	$0x05, %ah
+	je	1f			/* Jump if real part is +-Inf */
+	cmpb	$0x01, %ah
+	je	2f			/* Jump if real part is NaN */
+
+	fxam				/* y : x */
+	fnstsw
+	/* If the imaginary part is not finite we return NaN+i NaN, as
+	   for the case when the real part is NaN.  A test for +-Inf and
+	   NaN would be necessary.  But since we know the stack register
+	   we applied `fxam' to is not empty we can simply use one test.
+	   Check your FPU manual for more information.  */
+	andb	$0x01, %ah
+	cmpb	$0x01, %ah
+	je	2f
+
+	/* We have finite numbers in the real and imaginary part.  Do
+	   the real work now.  */
+	fxch			/* x : y */
+	fldt	MO(l2e)		/* log2(e) : x : y */
+	fmulp			/* x * log2(e) : y */
+	fld	%st		/* x * log2(e) : x * log2(e) : y */
+	frndint			/* int(x * log2(e)) : x * log2(e) : y */
+	fsubr	%st, %st(1)	/* int(x * log2(e)) : frac(x * log2(e)) : y */
+	fxch			/* frac(x * log2(e)) : int(x * log2(e)) : y */
+	f2xm1			/* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
+	faddl	MO(one)		/* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
+	fscale			/* e^x : int(x * log2(e)) : y */
+	fst	%st(1)		/* e^x : e^x : y */
+	fxch	%st(2)		/* y : e^x : e^x */
+	fsincos			/* cos(y) : sin(y) : e^x : e^x */
+	fnstsw
+	testl	$0x400, %eax
+	jnz	7f
+	fmulp	%st, %st(3)	/* sin(y) : e^x : e^x * cos(y) */
+	fmulp	%st, %st(1)	/* e^x * sin(y) : e^x * cos(y) */
+	subl	$8, %esp
+	fstps	4(%esp)
+	fstps	(%esp)
+	popl	%eax
+	popl	%edx
+	ret
+
+	/* We have to reduce the argument to fsincos.  */
+	.align ALIGNARG(4)
+7:	fldt	MO(twopi)	/* 2*pi : y : e^x : e^x */
+	fxch			/* y : 2*pi : e^x : e^x */
+8:	fprem1			/* y%(2*pi) : 2*pi : e^x : e^x */
+	fnstsw
+	testl	$0x400, %eax
+	jnz	8b
+	fstp	%st(1)		/* y%(2*pi) : e^x : e^x */
+	fsincos			/* cos(y) : sin(y) : e^x : e^x */
+	fmulp	%st, %st(3)
+	fmulp	%st, %st(1)
+	subl	$8, %esp
+	fstps	4(%esp)
+	fstps	(%esp)
+	popl	%eax
+	popl	%edx
+	ret
+
+	/* The real part is +-inf.  We must make further differences.  */
+	.align ALIGNARG(4)
+1:	fxam			/* y : x */
+	fnstsw
+	movb	%ah, %dl
+	andb	$0x01, %ah	/* See above why 0x01 is usable here.  */
+	cmpb	$0x01, %ah
+	je	3f
+
+
+	/* The real part is +-Inf and the imaginary part is finite.  */
+	andl	$0x245, %edx
+	cmpb	$0x40, %dl	/* Imaginary part == 0?  */
+	je	4f		/* Yes ->  */
+
+	fxch			/* x : y */
+	shrl	$6, %edx
+	fstp	%st(0)		/* y */ /* Drop the real part.  */
+	andl	$8, %edx	/* This puts the sign bit of the real part
+				   in bit 3.  So we can use it to index a
+				   small array to select 0 or Inf.  */
+	fsincos			/* cos(y) : sin(y) */
+	fnstsw
+	testl	$0x0400, %eax
+	jnz	5f
+	fxch
+	ftst
+	fnstsw
+	fstp	%st(0)
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	MOX(huge_nan_null_null,%edx,1), %eax
+	movl	MOX(huge_nan_null_null,%edx,1), %ecx
+	movl	%eax, %edx
+	ftst
+	fnstsw
+	fstp	%st(0)
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	%ecx, %eax
+	ret
+	/* We must reduce the argument to fsincos.  */
+	.align ALIGNARG(4)
+5:	fldt	MO(twopi)
+	fxch
+6:	fprem1
+	fnstsw
+	testl	$0x400, %eax
+	jnz	6b
+	fstp	%st(1)
+	fsincos
+	fxch
+	ftst
+	fnstsw
+	fstp	%st(0)
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	MOX(huge_nan_null_null,%edx,1), %eax
+	movl	MOX(huge_nan_null_null,%edx,1), %ecx
+	movl	%eax, %edx
+	ftst
+	fnstsw
+	fstp	%st(0)
+	shll	$23, %eax
+	andl	$0x80000000, %eax
+	orl	%ecx, %eax
+	ret
+
+	/* The real part is +-Inf and the imaginary part is +-0.  So return
+	   +-Inf+-0i.  */
+	.align ALIGNARG(4)
+4:	subl	$4, %esp
+	fstps	(%esp)
+	shrl	$6, %edx
+	fstp	%st(0)
+	andl	$8, %edx
+	movl	MOX(huge_nan_null_null,%edx,1), %eax
+	popl	%edx
+	ret
+
+	/* The real part is +-Inf, the imaginary is also is not finite.  */
+	.align ALIGNARG(4)
+3:	fstp	%st(0)
+	fstp	%st(0)		/* <empty> */
+	movl	%edx, %eax
+	shrl	$6, %edx
+	shll	$3, %eax
+	andl	$8, %edx
+	andl	$16, %eax
+	orl	%eax, %edx
+
+	movl	MOX(huge_nan_null_null,%edx,1), %eax
+	movl	MOX(huge_nan_null_null+4,%edx,1), %edx
+	ret
+
+	/* The real part is NaN.  */
+	.align ALIGNARG(4)
+2:	fstp	%st(0)
+	fstp	%st(0)
+	movl	MO(huge_nan_null_null+4), %eax
+	movl	%eax, %edx
+	ret
+
+END(__cexpf)
+weak_alias (__cexpf, cexpf)
diff --git a/sysdeps/libm-i387/s_cexpl.S b/sysdeps/libm-i387/s_cexpl.S
new file mode 100644
index 0000000000..fa31e74162
--- /dev/null
+++ b/sysdeps/libm-i387/s_cexpl.S
@@ -0,0 +1,249 @@
+/* ix87 specific implementation of complex exponential function for double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <sysdep.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
+huge_nan_null_null:
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	.double	0.0
+	.double	0.0
+	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	.double 0.0
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	ASM_SIZE_DIRECTIVE(huge_nan_null_null)
+
+	ASM_TYPE_DIRECTIVE(twopi,@object)
+twopi:
+	.byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
+	.byte 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(twopi)
+
+	ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:
+	.byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
+	.byte 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(l2e)
+
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+
+
+#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(__cexpl)
+	fldt	8(%esp)			/* x */
+	fxam
+	fnstsw
+	fldt	20(%esp)		/* y : x */
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	movb	%ah, %dh
+	andb	$0x45, %ah
+	cmpb	$0x05, %ah
+	je	1f			/* Jump if real part is +-Inf */
+	cmpb	$0x01, %ah
+	je	2f			/* Jump if real part is NaN */
+
+	fxam				/* y : x */
+	fnstsw
+	/* If the imaginary part is not finite we return NaN+i NaN, as
+	   for the case when the real part is NaN.  A test for +-Inf and
+	   NaN would be necessary.  But since we know the stack register
+	   we applied `fxam' to is not empty we can simply use one test.
+	   Check your FPU manual for more information.  */
+	andb	$0x01, %ah
+	cmpb	$0x01, %ah
+	je	2f
+
+	/* We have finite numbers in the real and imaginary part.  Do
+	   the real work now.  */
+	fxch			/* x : y */
+	fldt	MO(l2e)		/* log2(e) : x : y */
+	fmulp			/* x * log2(e) : y */
+	fld	%st		/* x * log2(e) : x * log2(e) : y */
+	frndint			/* int(x * log2(e)) : x * log2(e) : y */
+	fsubr	%st, %st(1)	/* int(x * log2(e)) : frac(x * log2(e)) : y */
+	fxch			/* frac(x * log2(e)) : int(x * log2(e)) : y */
+	f2xm1			/* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
+	faddl	MO(one)		/* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
+	fscale			/* e^x : int(x * log2(e)) : y */
+	fst	%st(1)		/* e^x : e^x : y */
+	fxch	%st(2)		/* y : e^x : e^x */
+	fsincos			/* cos(y) : sin(y) : e^x : e^x */
+	fnstsw
+	testl	$0x400, %eax
+	jnz	7f
+	fmulp	%st, %st(3)	/* sin(y) : e^x : e^x * cos(y) */
+	fmulp	%st, %st(1)	/* e^x * sin(y) : e^x * cos(y) */
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fstpt	12(%eax)
+	fstpt	(%eax)
+	ret	$4
+
+	/* We have to reduce the argument to fsincos.  */
+	.align ALIGNARG(4)
+7:	fldt	MO(twopi)	/* 2*pi : y : e^x : e^x */
+	fxch			/* y : 2*pi : e^x : e^x */
+8:	fprem1			/* y%(2*pi) : 2*pi : e^x : e^x */
+	fnstsw
+	testl	$0x400, %eax
+	jnz	8b
+	fstp	%st(1)		/* y%(2*pi) : e^x : e^x */
+	fsincos			/* cos(y) : sin(y) : e^x : e^x */
+	fmulp	%st, %st(3)
+	fmulp	%st, %st(1)
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fstpt	12(%eax)
+	fstpt	(%eax)
+	ret	$4
+
+	/* The real part is +-inf.  We must make further differences.  */
+	.align ALIGNARG(4)
+1:	fxam			/* y : x */
+	fnstsw
+	movb	%ah, %dl
+	andb	$0x01, %ah	/* See above why 0x01 is usable here.  */
+	cmpb	$0x01, %ah
+	je	3f
+
+
+	/* The real part is +-Inf and the imaginary part is finite.  */
+	andl	$0x245, %edx
+	cmpb	$0x40, %dl	/* Imaginary part == 0?  */
+	je	4f		/* Yes ->  */
+
+	fxch			/* x : y */
+	shrl	$5, %edx
+	fstp	%st(0)		/* y */ /* Drop the real part.  */
+	andl	$16, %edx	/* This puts the sign bit of the real part
+				   in bit 4.  So we can use it to index a
+				   small array to select 0 or Inf.  */
+	fsincos			/* cos(y) : sin(y) */
+	fnstsw
+	testl	$0x0400, %eax
+	jnz	5f
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	movl	4(%esp), %edx		/* Pointer to memory for result.  */
+	fstl	8(%edx)
+	fstpl	(%edx)
+	ftst
+	fnstsw
+	shll	$7, %eax
+	andl	$0x8000, %eax
+	orl	%eax, 8(%edx)
+	fstp	%st(0)
+	ftst
+	fnstsw
+	shll	$7, %eax
+	andl	$0x8000, %eax
+	orl	%eax, 20(%edx)
+	fstp	%st(0)
+	ret	$4
+	/* We must reduce the argument to fsincos.  */
+	.align ALIGNARG(4)
+5:	fldt	MO(twopi)
+	fxch
+6:	fprem1
+	fnstsw
+	testl	$0x400, %eax
+	jnz	6b
+	fstp	%st(1)
+	fsincos
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	movl	4(%esp), %edx		/* Pointer to memory for result.  */
+	fstl	8(%edx)
+	fstpl	(%edx)
+	ftst
+	fnstsw
+	shll	$7, %eax
+	andl	$0x8000, %eax
+	orl	%eax, 8(%edx)
+	fstp	%st(0)
+	ftst
+	fnstsw
+	shll	$7, %eax
+	andl	$0x8000, %eax
+	orl	%eax, 20(%edx)
+	fstp	%st(0)
+	ret	$4
+
+	/* The real part is +-Inf and the imaginary part is +-0.  So return
+	   +-Inf+-0i.  */
+	.align ALIGNARG(4)
+4:	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fstpt	12(%eax)
+	shrl	$5, %edx
+	fstp	%st(0)
+	andl	$16, %edx
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	fstpt	(%eax)
+	ret	$4
+
+	/* The real part is +-Inf, the imaginary is also is not finite.  */
+	.align ALIGNARG(4)
+3:	fstp	%st(0)
+	fstp	%st(0)		/* <empty> */
+	movl	%edx, %eax
+	shrl	$5, %edx
+	shll	$4, %eax
+	andl	$16, %edx
+	andl	$32, %eax
+	orl	%eax, %edx
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+
+	fldl	MOX(huge_nan_null_null,%edx,1)
+	fldl	MOX(huge_nan_null_null+8,%edx,1)
+	fstpt	12(%eax)
+	fstpt	(%eax)
+	ret	$4
+
+	/* The real part is NaN.  */
+	.align ALIGNARG(4)
+2:	fstp	%st(0)
+	fstp	%st(0)
+	movl	4(%esp), %eax		/* Pointer to memory for result.  */
+	fldl	MO(huge_nan_null_null+8)
+	fld	%st(0)
+	fstpt	(%eax)
+	fstpt	12(%eax)
+	ret	$4
+
+END(__cexpl)
+weak_alias (__cexpl, cexpl)
diff --git a/sysdeps/libm-ieee754/s_ccosh.c b/sysdeps/libm-ieee754/s_ccosh.c
new file mode 100644
index 0000000000..f01b245e77
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_ccosh.c
@@ -0,0 +1,95 @@
+/* Complex cosine hyperbole function for double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <complex.h>
+#include <math.h>
+
+
+__complex__ double
+__ccosh (__complex__ double x)
+{
+  __complex__ double retval;
+
+  __real__ x = fabs (__real__ x);
+
+  if (isfinite (__real__ x))
+    {
+      if (isfinite (__imag__ x))
+	{
+	  double exp_val = __exp (__real__ x);
+	  double rec_exp_val = 1.0 / exp_val;
+
+	  __real__ retval = 0.5 * (exp_val + rec_exp_val) * __cos (__imag__ x);
+	  __imag__ retval = 0.5 * (exp_val + rec_exp_val) * __sin (__imag__ x);
+	}
+      else
+	{
+	  if (__real__ x == 0)
+	    {
+	      __imag__ retval = 0.0;
+	      __real__ retval = __nan ("") + __nan ("");
+	    }
+	  else
+	    {
+	      __real__ retval = __nan ("");
+	      __imag__ retval = __nan ("") + __nan ("");
+	    }
+	}
+    }
+  else if (__isinf (__real__ x))
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = HUGE_VAL;
+	  __imag__ retval = __imag__ x;
+	}
+      else if (isfinite (__imag__ x))
+	{
+	  __real__ retval = __copysign (HUGE_VAL, __cos (__imag__ x));
+	  __imag__ retval = __copysign (HUGE_VAL, __sin (__imag__ x));
+	}
+      else
+	{
+	  /* The addition raises the invalid exception.  */
+	  __real__ retval = HUGE_VAL;
+	  __imag__ retval = __nan ("") + __nan ("");
+	}
+    }
+  else
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = __nan ("");
+	  __imag__ retval = __imag__ x;
+	}
+      else
+	{
+	  __real__ retval = __nan ("");
+	  __imag__ retval = __nan ("");
+	}
+    }
+
+  return retval;
+}
+weak_alias (__ccosh, ccosh)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__ccosh, __ccoshl)
+weak_alias (__ccosh, ccoshl)
+#endif
diff --git a/sysdeps/libm-ieee754/s_ccoshf.c b/sysdeps/libm-ieee754/s_ccoshf.c
new file mode 100644
index 0000000000..9f2774b6c7
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_ccoshf.c
@@ -0,0 +1,93 @@
+/* Complex cosine hyperbole function for float.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <complex.h>
+#include <math.h>
+
+
+__complex__ float
+__ccoshf (__complex__ float x)
+{
+  __complex__ float retval;
+
+  __real__ x = fabsf (__real__ x);
+
+  if (isfinite (__real__ x))
+    {
+      if (isfinite (__imag__ x))
+	{
+	  float exp_val = __expf (__real__ x);
+	  float rec_exp_val = 1.0 / exp_val;
+
+	  __real__ retval = (0.5 * (exp_val + rec_exp_val)
+			     * __cosf (__imag__ x));
+	  __imag__ retval = (0.5 * (exp_val + rec_exp_val)
+			     * __sinf (__imag__ x));
+	}
+      else
+	{
+	  if (__real__ x == 0)
+	    {
+	      __imag__ retval = 0.0;
+	      __real__ retval = __nanf ("") + __nanf ("");
+	    }
+	  else
+	    {
+	      __real__ retval = __nanf ("");
+	      __imag__ retval = __nanf ("") + __nanf ("");
+	    }
+	}
+    }
+  else if (__isinff (__real__ x))
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = HUGE_VALF;
+	  __imag__ retval = __imag__ x;
+	}
+      else if (isfinite (__imag__ x))
+	{
+	  __real__ retval = __copysignf (HUGE_VALF, __cosf (__imag__ x));
+	  __imag__ retval = __copysignf (HUGE_VALF, __sinf (__imag__ x));
+	}
+      else
+	{
+	  /* The addition raises the invalid exception.  */
+	  __real__ retval = HUGE_VALF;
+	  __imag__ retval = __nanf ("") + __nanf ("");
+	}
+    }
+  else
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = __nanf ("");
+	  __imag__ retval = __imag__ x;
+	}
+      else
+	{
+	  __real__ retval = __nanf ("");
+	  __imag__ retval = __nanf ("");
+	}
+    }
+
+  return retval;
+}
+weak_alias (__ccoshf, ccoshf)
diff --git a/sysdeps/libm-ieee754/s_ccoshl.c b/sysdeps/libm-ieee754/s_ccoshl.c
new file mode 100644
index 0000000000..fd553418b4
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_ccoshl.c
@@ -0,0 +1,93 @@
+/* Complex cosine hyperbole function for long double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <complex.h>
+#include <math.h>
+
+
+__complex__ long double
+__ccoshl (__complex__ long double x)
+{
+  __complex__ long double retval;
+
+  __real__ x = fabsl (__real__ x);
+
+  if (isfinite (__real__ x))
+    {
+      if (isfinite (__imag__ x))
+	{
+	  long double exp_val = __expl (__real__ x);
+	  long double rec_exp_val = 1.0 / exp_val;
+
+	  __real__ retval = (0.5 * (exp_val + rec_exp_val)
+			     * __cosl (__imag__ x));
+	  __imag__ retval = (0.5 * (exp_val + rec_exp_val)
+			     * __sinl (__imag__ x));
+	}
+      else
+	{
+	  if (__real__ x == 0)
+	    {
+	      __imag__ retval = 0.0;
+	      __real__ retval = __nanl ("") + __nanl ("");
+	    }
+	  else
+	    {
+	      __real__ retval = __nanl ("");
+	      __imag__ retval = __nanl ("") + __nanl ("");
+	    }
+	}
+    }
+  else if (__isinfl (__real__ x))
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = HUGE_VALL;
+	  __imag__ retval = __imag__ x;
+	}
+      else if (isfinite (__imag__ x))
+	{
+	  __real__ retval = __copysignl (HUGE_VALL, __cosl (__imag__ x));
+	  __imag__ retval = __copysignl (HUGE_VALL, __sinl (__imag__ x));
+	}
+      else
+	{
+	  /* The addition raises the invalid exception.  */
+	  __real__ retval = HUGE_VALL;
+	  __imag__ retval = __nanl ("") + __nanl ("");
+	}
+    }
+  else
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = __nanl ("");
+	  __imag__ retval = __imag__ x;
+	}
+      else
+	{
+	  __real__ retval = __nanl ("");
+	  __imag__ retval = __nanl ("");
+	}
+    }
+
+  return retval;
+}
+weak_alias (__ccoshl, ccoshl)
diff --git a/sysdeps/libm-ieee754/s_cexp.c b/sysdeps/libm-ieee754/s_cexp.c
index 46f9f612eb..233a40014f 100644
--- a/sysdeps/libm-ieee754/s_cexp.c
+++ b/sysdeps/libm-ieee754/s_cexp.c
@@ -1,4 +1,4 @@
-/* Return value of complex exponential function for double complex value.
+/* Return value of complex exponential function for float complex value.
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -31,33 +31,52 @@ __cexp (__complex__ double x)
     {
       if (isfinite (__imag__ x))
 	{
-	  retval = __exp (__real__ x) * (__cos (__imag__ x)
-					 + 1i * __sin (__imag__ x));
+	  double exp_val = __exp (__real__ x);
+
+	  __real__ retval = exp_val * __cos (__imag__ x);
+	  __imag__ retval = exp_val * __sin (__imag__ x);
 	}
       else
-	/* If the imaginary part is +-inf or NaN and the real part is
-	   not +-inf the result is NaN + iNan.  */
-	retval = __nan ("") + 1.0i * __nan ("");
+	{
+	  /* If the imaginary part is +-inf or NaN and the real part
+	     is not +-inf the result is NaN + iNaN.  */
+	  __real__ retval = __nan ("");
+	  __imag__ retval = __nan ("");
+	}
     }
   else if (__isinf (__real__ x))
     {
-      if (isfinite (__imag x))
+      if (isfinite (__imag__ x))
 	{
 	  if (signbit (__real__ x) == 0 && __imag__ x == 0.0)
 	    retval = HUGE_VAL;
 	  else
-	    retval = ((signbit (__real__ x) ? 0.0 : HUGE_VAL)
-		      * (__cos (__imag__ x) + 1i * __sin (__imag__ x)));
+	    {
+	      double value = signbit (__real__ x) ? 0.0 : HUGE_VAL;
+
+	      __real__ retval = value * __cos (__imag__ x);
+	      __imag__ retval = value * __sin (__imag__ x);
+	    }
+	}
+      else if (signbit (__real__ x) == 0)
+	{
+	  __real__ retval = HUGE_VAL;
+	  __imag__ retval = __nan ("");
 	}
-      else if (signbit (__real__ x))
-	retval = HUGE_VAL + 1.0i * __nan ("");
       else
 	retval = 0.0;
     }
   else
-    /* If the real part is NaN the result is NaN + iNan.  */
-    retval = __nan ("") + 1.0i * __nan ("");
+    {
+      /* If the real part is NaN the result is NaN + iNaN.  */
+      __real__ retval = __nan ("");
+      __imag__ retval = __nan ("");
+    }
 
   return retval;
 }
 weak_alias (__cexp, cexp)
+#ifdef NO_LONG_DOUBLE
+string_alias (__cexp, __cexpl)
+weak_alias (__cexp, cexpl)
+#endif
diff --git a/sysdeps/libm-ieee754/s_cexpf.c b/sysdeps/libm-ieee754/s_cexpf.c
index 261b18cb3a..c5d8f0cc07 100644
--- a/sysdeps/libm-ieee754/s_cexpf.c
+++ b/sysdeps/libm-ieee754/s_cexpf.c
@@ -33,8 +33,16 @@ __cexpf (__complex__ float x)
 	{
 	  float exp_val = __expf (__real__ x);
 
-	  __real__ retval = exp_val * __cosf (__imag__ x);
-	  __imag__ retval = exp_val * __sinf (__imag__ x);
+	  if (isfinite (exp_val))
+	    {
+	      __real__ retval = exp_val * __cosf (__imag__ x);
+	      __imag__ retval = exp_val * __sinf (__imag__ x);
+	    }
+	  else
+	    {
+	      __real__ retval = __copysignf (exp_val, __cosf (__imag__ x));
+	      __imag__ retval = __copysignf (exp_val, __sinf (__imag__ x));
+	    }
 	}
       else
 	{
@@ -48,14 +56,17 @@ __cexpf (__complex__ float x)
     {
       if (isfinite (__imag__ x))
 	{
-	  if (signbit (__real__ x) == 0 && __imag__ x == 0.0)
-	    retval = HUGE_VALF;
+	  float value = signbit (__real__ x) ? 0.0 : HUGE_VALF;
+
+	  if (__imag__ x == 0.0)
+	    {
+	      __real__ retval = value;
+	      __imag__ retval = __imag__ x;
+	    }
 	  else
 	    {
-	      float value = signbit (__real__ x) ? 0.0 : HUGE_VALF;
-
-	      __real__ retval = value * __cosf (__imag__ x);
-	      __imag__ retval = value * __sinf (__imag__ x);
+	      __real__ retval = __copysignf (value, __cosf (__imag__ x));
+	      __imag__ retval = __copysignf (value, __sinf (__imag__ x));
 	    }
 	}
       else if (signbit (__real__ x) == 0)
@@ -64,7 +75,10 @@ __cexpf (__complex__ float x)
 	  __imag__ retval = __nanf ("");
 	}
       else
-	retval = 0.0;
+	{
+	  __real__ retval = 0.0;
+	  __imag__ retval = __copysignf (0.0, __imag__ x);
+	}
     }
   else
     {
diff --git a/sysdeps/libm-ieee754/s_cexpl.c b/sysdeps/libm-ieee754/s_cexpl.c
index 779286f6b3..f1cdf43ec8 100644
--- a/sysdeps/libm-ieee754/s_cexpl.c
+++ b/sysdeps/libm-ieee754/s_cexpl.c
@@ -33,8 +33,16 @@ __cexpl (__complex__ long double x)
 	{
 	  long double exp_val = __expl (__real__ x);
 
-	  __real__ retval = exp_val * __cosl (__imag__ x);
-	  __imag__ retval = exp_val * __sinl (__imag__ x);
+	  if (isfinite (exp_val))
+	    {
+	      __real__ retval = exp_val * __cosl (__imag__ x);
+	      __imag__ retval = exp_val * __sinl (__imag__ x);
+	    }
+	  else
+	    {
+	      __real__ retval = __copysignl (exp_val, __cosl (__imag__ x));
+	      __imag__ retval = __copysignl (exp_val, __sinl (__imag__ x));
+	    }
 	}
       else
 	{
@@ -48,14 +56,17 @@ __cexpl (__complex__ long double x)
     {
       if (isfinite (__imag__ x))
 	{
-	  if (signbit (__real__ x) == 0 && __imag__ x == 0.0)
-	    retval = HUGE_VAL;
+	  long double value = signbit (__real__ x) ? 0.0 : HUGE_VALL;
+
+	  if (__imag__ x == 0.0)
+	    {
+	      __real__ retval = value;
+	      __imag__ retval = __imag__ x;
+	    }
 	  else
 	    {
-	      long double value = signbit (__real__ x) ? 0.0 : HUGE_VALL;
-
-	      __real__ retval = value * __cosl (__imag__ x);
-	      __imag__ retval = value * __sinl (__imag__ x);
+	      __real__ retval = __copysignl (value, __cosl (__imag__ x));
+	      __imag__ retval = __copysignl (value, __sinl (__imag__ x));
 	    }
 	}
       else if (signbit (__real__ x) == 0)
@@ -64,7 +75,10 @@ __cexpl (__complex__ long double x)
 	  __imag__ retval = __nanl ("");
 	}
       else
-	retval = 0.0;
+	{
+	  __real__ retval = 0.0;
+	  __imag__ retval = __copysignl (0.0, __imag__ x);
+	}
     }
   else
     {
diff --git a/sysdeps/libm-ieee754/s_csinh.c b/sysdeps/libm-ieee754/s_csinh.c
new file mode 100644
index 0000000000..aab041bdf9
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_csinh.c
@@ -0,0 +1,102 @@
+/* Complex sine hyperbole function for double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <complex.h>
+#include <math.h>
+
+
+__complex__ double
+__csinh (__complex__ double x)
+{
+  __complex__ double retval;
+  int negate = signbit (__real__ x);
+
+  __real__ x = fabs (__real__ x);
+
+  if (isfinite (__real__ x))
+    {
+      if (isfinite (__imag__ x))
+	{
+	  double exp_val = __exp (__real__ x);
+	  double rec_exp_val = 1.0 / exp_val;
+
+	  __real__ retval = 0.5 * (exp_val - rec_exp_val) * __cos (__imag__ x);
+	  __imag__ retval = 0.5 * (exp_val - rec_exp_val) * __sin (__imag__ x);
+
+	  if (negate)
+	    __real__ retval = -__real__ retval;
+	}
+      else
+	{
+	  if (__real__ x == 0)
+	    {
+	      __real__ retval = __copysign (0.0, negate ? -1.0 : 1.0);
+	      __imag__ retval = __nan ("") + __nan ("");
+	    }
+	  else
+	    {
+	      __real__ retval = __nan ("");
+	      __imag__ retval = __nan ("");
+	    }
+	}
+    }
+  else if (__isinf (__real__ x))
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = negate ? -HUGE_VAL : HUGE_VAL;
+	  __imag__ retval = __imag__ x;
+	}
+      else if (isfinite (__imag__ x))
+	{
+	  __real__ retval = __copysign (HUGE_VAL, __cos (__imag__ x));
+	  __imag__ retval = __copysign (HUGE_VAL, __sin (__imag__ x));
+
+	  if (negate)
+	    __real__ retval = -__real__ retval;
+	}
+      else
+	{
+	  /* The addition raises the invalid exception.  */
+	  __real__ retval = HUGE_VAL;
+	  __imag__ retval = __nan ("") + __nan ("");
+	}
+    }
+  else
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = __nan ("");
+	  __imag__ retval = __imag__ x;
+	}
+      else
+	{
+	  __real__ retval = __nan ("");
+	  __imag__ retval = __nan ("");
+	}
+    }
+
+  return retval;
+}
+weak_alias (__csinh, csinh)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__csinh, __csinhl)
+weak_alias (__csinh, csinhl)
+#endif
diff --git a/sysdeps/libm-ieee754/s_csinhf.c b/sysdeps/libm-ieee754/s_csinhf.c
new file mode 100644
index 0000000000..204bbfebb9
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_csinhf.c
@@ -0,0 +1,100 @@
+/* Complex sine hyperbole function for float.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <complex.h>
+#include <math.h>
+
+
+__complex__ float
+__csinhf (__complex__ float x)
+{
+  __complex__ float retval;
+  int negate = signbit (__real__ x);
+
+  __real__ x = fabsf (__real__ x);
+
+  if (isfinite (__real__ x))
+    {
+      if (isfinite (__imag__ x))
+	{
+	  float exp_val = __expf (__real__ x);
+	  float rec_exp_val = 1.0 / exp_val;
+
+	  __real__ retval = (0.5 * (exp_val - rec_exp_val)
+			     * __cosf (__imag__ x));
+	  __imag__ retval = (0.5 * (exp_val - rec_exp_val)
+			     * __sinf (__imag__ x));
+
+	  if (negate)
+	    __real__ retval = -__real__ retval;
+	}
+      else
+	{
+	  if (__real__ x == 0)
+	    {
+	      __real__ retval = __copysignf (0.0, negate ? -1.0 : 1.0);
+	      __imag__ retval = __nanf ("") + __nanf ("");
+	    }
+	  else
+	    {
+	      __real__ retval = __nanf ("");
+	      __imag__ retval = __nanf ("");
+	    }
+	}
+    }
+  else if (__isinff (__real__ x))
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = negate ? -HUGE_VALF : HUGE_VALF;
+	  __imag__ retval = __imag__ x;
+	}
+      else if (isfinite (__imag__ x))
+	{
+	  __real__ retval = __copysignf (HUGE_VALF, __cosf (__imag__ x));
+	  __imag__ retval = __copysignf (HUGE_VALF, __sinf (__imag__ x));
+
+	  if (negate)
+	    __real__ retval = -__real__ retval;
+	}
+      else
+	{
+	  /* The addition raises the invalid exception.  */
+	  __real__ retval = HUGE_VALF;
+	  __imag__ retval = __nanf ("") + __nanf ("");
+	}
+    }
+  else
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = __nanf ("");
+	  __imag__ retval = __imag__ x;
+	}
+      else
+	{
+	  __real__ retval = __nanf ("");
+	  __imag__ retval = __nanf ("");
+	}
+    }
+
+  return retval;
+}
+weak_alias (__csinhf, csinhf)
diff --git a/sysdeps/libm-ieee754/s_csinhl.c b/sysdeps/libm-ieee754/s_csinhl.c
new file mode 100644
index 0000000000..e403dd4796
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_csinhl.c
@@ -0,0 +1,100 @@
+/* Complex sine hyperbole function for long double.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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.  */
+
+#include <complex.h>
+#include <math.h>
+
+
+__complex__ long double
+__csinhl (__complex__ long double x)
+{
+  __complex__ long double retval;
+  int negate = signbit (__real__ x);
+
+  __real__ x = fabs (__real__ x);
+
+  if (isfinite (__real__ x))
+    {
+      if (isfinite (__imag__ x))
+	{
+	  long double exp_val = __expl (__real__ x);
+	  long double rec_exp_val = 1.0 / exp_val;
+
+	  __real__ retval = (0.5 * (exp_val - rec_exp_val)
+			     * __cosl (__imag__ x));
+	  __imag__ retval = (0.5 * (exp_val - rec_exp_val)
+			     * __sinl (__imag__ x));
+
+	  if (negate)
+	    __real__ retval = -__real__ retval;
+	}
+      else
+	{
+	  if (__real__ x == 0)
+	    {
+	      __real__ retval = __copysignl (0.0, negate ? -1.0 : 1.0);
+	      __imag__ retval = __nanl ("") + __nanl ("");
+	    }
+	  else
+	    {
+	      __real__ retval = __nanl ("");
+	      __imag__ retval = __nanl ("");
+	    }
+	}
+    }
+  else if (__isinfl (__real__ x))
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = negate ? -HUGE_VALL : HUGE_VALL;
+	  __imag__ retval = __imag__ x;
+	}
+      else if (isfinite (__imag__ x))
+	{
+	  __real__ retval = __copysignl (HUGE_VALL, __cosl (__imag__ x));
+	  __imag__ retval = __copysignl (HUGE_VALL, __sinl (__imag__ x));
+
+	  if (negate)
+	    __real__ retval = -__real__ retval;
+	}
+      else
+	{
+	  /* The addition raises the invalid exception.  */
+	  __real__ retval = HUGE_VALL;
+	  __imag__ retval = __nanl ("") + __nanl ("");
+	}
+    }
+  else
+    {
+      if (__imag__ x == 0.0)
+	{
+	  __real__ retval = __nanl ("");
+	  __imag__ retval = __imag__ x;
+	}
+      else
+	{
+	  __real__ retval = __nanl ("");
+	  __imag__ retval = __nanl ("");
+	}
+    }
+
+  return retval;
+}
+weak_alias (__csinhl, csinhl)
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 4d32ee02ac..f819bb4c0c 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -45,7 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /* getaddrinfo() v1.13 */
 
 /* To do what POSIX says, even when it's broken: */
-/* #define BROKEN_LIKE_POSIX 1 */
+#define BROKEN_LIKE_POSIX 1
 #define LOCAL 1
 #define INET6 1
 #define HOSTTABLE 0
@@ -168,21 +168,34 @@ static int gaih_local(const char *name, const struct gaih_service *service,
 };
 #endif /* LOCAL */
 
-static struct gaih_typeproto gaih_inet_typeproto[] = {
+static struct gaih_typeproto gaih_inet_typeproto[] =
+{
   { 0, 0, NULL },
-  { SOCK_STREAM, IPPROTO_TCP, (char *)"tcp" },
-  { SOCK_DGRAM, IPPROTO_UDP, (char *)"udp" },
+  { SOCK_STREAM, IPPROTO_TCP, (char *) "tcp" },
+  { SOCK_DGRAM, IPPROTO_UDP, (char *) "udp" },
   { 0, 0, NULL }
 };
 
 static int gaih_inet_serv(char *servicename, struct gaih_typeproto *tp, struct gaih_servtuple **st)
 {
   struct servent *s;
+  int tmpbuflen = 1024;
+  struct servent ts;
+  char *tmpbuf = __alloca (tmpbuflen);
+  while (__getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen, &s))
+    {
+      if (errno == ERANGE)
+	{
+	  tmpbuflen *= 2;
+	  tmpbuf = __alloca (tmpbuflen);
+	}
+      else
+	{
+	  return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+	}
+    }
 
-  if (!(s = getservbyname(servicename, tp->name)))
-    return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
-
-  if (!(*st = malloc(sizeof(struct gaih_servtuple))))
+  if (!(*st = malloc (sizeof (struct gaih_servtuple))))
     return -EAI_MEMORY;
 
   (*st)->next = NULL;
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
index b1a685c29a..2b8f9cb590 100644
--- a/sysdeps/posix/system.c
+++ b/sysdeps/posix/system.c
@@ -1,20 +1,20 @@
-/* Copyright (C) 1991, 92, 94, 95, 96 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, 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 <stddef.h>
 #include <stdlib.h>
diff --git a/sysdeps/sparc/dl-machine.h b/sysdeps/sparc/dl-machine.h
index cadf353878..ceaf9eedce 100644
--- a/sysdeps/sparc/dl-machine.h
+++ b/sysdeps/sparc/dl-machine.h
@@ -105,7 +105,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   Elf32_Addr loadbase;
 
   if (ELF32_R_TYPE (reloc->r_info) == R_SPARC_RELATIVE)
-    *reloc_addr += map->l_addr + reloc->r_addend;
+    {
+#ifndef RTLD_BOOTSTRAP
+      if (map != &_dl_rtld_map) /* Already done in rtld itself. */
+#endif
+	*reloc_addr += map->l_addr + reloc->r_addend;
+    }
   else
     {
       Elf32_Addr value;
diff --git a/sysdeps/sparc/udiv_qrnnd.S b/sysdeps/sparc/udiv_qrnnd.S
index 4cd4f051b3..e5d30679e1 100644
--- a/sysdeps/sparc/udiv_qrnnd.S
+++ b/sysdeps/sparc/udiv_qrnnd.S
@@ -1,6 +1,6 @@
 ! SPARC  __udiv_qrnnd division support, used from longlong.h.
 
-! Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
 
 ! This file is part of the GNU MP Library.
 
@@ -18,6 +18,8 @@
 ! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
 ! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
+!
+! Added PIC support - May/96, Miguel de Icaza
 
 ! INPUT PARAMETERS
 ! rem_ptr	i0
@@ -25,6 +27,7 @@
 ! n0		i2
 ! d		i3
 
+#include "DEFS.h"
 #include "sysdep.h"
 #undef ret	/* Kludge for glibc */
 
@@ -34,16 +37,25 @@ LC0:	.double	0r4294967296
 LC1:	.double	0r2147483648
 
 	.align	4
-	.global	C_SYMBOL_NAME(__udiv_qrnnd)
-C_SYMBOL_NAME(__udiv_qrnnd):
+	.global	__udiv_qrnnd
+FUNC(__udiv_qrnnd)
 	!#PROLOGUE# 0
 	save	%sp,-104,%sp
 	!#PROLOGUE# 1
 	st	%i1,[%fp-8]
 	ld	[%fp-8],%f10
+#ifdef __PIC__
+._XL11:
+	call	._XL1
+	fitod	%f10,%f4
+._XL1:
+	sub	%o7,(._XL11-LC0),%o7
+	ldd	[%o7],%f8
+#else
 	sethi	%hi(LC0),%o7
 	fitod	%f10,%f4
 	ldd	[%o7+%lo(LC0)],%f8
+#endif
 	cmp	%i1,0
 	bge	L248
 	mov	%i0,%i5
@@ -66,8 +78,17 @@ L249:
 	faddd	%f4,%f8,%f4
 L250:
 	fdivd	%f2,%f4,%f2
+#ifdef __PIC__
+._XL22:
+	call	._XL2
+	nop
+._XL2:
+	sub	%o7,(._XL22-LC1),%o7
+	ldd	[%o7],%f4
+#else
 	sethi	%hi(LC1),%o7
 	ldd	[%o7+%lo(LC1)],%f4
+#endif
 	fcmped	%f2,%f4
 	nop
 	fbge,a	L251
diff --git a/sysdeps/unix/sysv/linux/sparc/Dist b/sysdeps/unix/sysv/linux/sparc/Dist
index b50a46fb68..ab22392c04 100644
--- a/sysdeps/unix/sysv/linux/sparc/Dist
+++ b/sysdeps/unix/sysv/linux/sparc/Dist
@@ -3,3 +3,5 @@ clone.S
 start.c
 pipe.S
 fork.S
+kernel_stat.h
+kernel_sigaction.h
diff --git a/sysdeps/unix/sysv/linux/sparc/fcntlbits.h b/sysdeps/unix/sysv/linux/sparc/fcntlbits.h
new file mode 100644
index 0000000000..3fc7240a66
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/fcntlbits.h
@@ -0,0 +1,96 @@
+/* O_*, F_*, FD_* bit values for Linux/SPARC.
+   Copyright (C) 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 _FCNTLBITS_H
+#define _FCNTLBITS_H	1
+
+#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. */
+#endif
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_RDONLY	0x0000
+#define O_WRONLY	0x0001
+#define O_RDWR		0x0002
+#define O_ACCMODE	0x0003
+#define O_APPEND	0x0008
+#define O_CREAT		0x0200	/* not fcntl */
+#define O_TRUNC		0x0400	/* not fcntl */
+#define O_EXCL		0x0800	/* not fcntl */
+#define O_SYNC		0x2000
+#define O_NONBLOCK	0x4000
+#define O_NDELAY	(0x0004 | O_NONBLOCK)
+#define O_NOCTTY	0x8000	/* not fcntl */
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get f_flags */
+#define F_SETFD		2	/* set f_flags */
+#define F_GETFL		3	/* more flags (cloexec) */
+#define F_SETFL		4
+#define F_GETOWN	5	/*  for sockets. */
+#define F_SETOWN	6	/*  for sockets. */
+#define F_GETLK		7
+#define F_SETLK		8
+#define F_SETLKW	9
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		1
+#define F_WRLCK		2
+#define F_UNLCK		3
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+struct flock
+  {
+    short int l_type;
+    short int l_whence;
+    __off_t l_start;
+    __off_t l_len;
+    __pid_t l_pid;
+    short int __unused;
+  };
+
+/* 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
diff --git a/sysdeps/unix/sysv/linux/sparc/ioctls.h b/sysdeps/unix/sysv/linux/sparc/ioctls.h
new file mode 100644
index 0000000000..80b2e62e77
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/ioctls.h
@@ -0,0 +1,39 @@
+/* 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 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 _IOCTLS_H
+#define _IOCTLS_H 1
+
+/* Use the definitions from the kernel header files.  */
+#include <asm/ioctls.h>
+#include <sys/kernel_termios.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+   different from the user-level version.  */
+#undef  TCGETS
+#undef  TCSETS
+#undef  TCSETSW
+#undef  TCSETSF
+#define TCGETS	_IOR ('t', 19, struct __kernel_termios)
+#define TCSETS	_IOW ('t', 20, struct __kernel_termios)
+#define TCSETSW	_IOW ('t', 21, struct __kernel_termios)
+#define TCSETSF	_IOW ('t', 22, struct __kernel_termios)
+
+#include <linux/sockios.h>
+
+#endif /* ioctls.h  */
diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
new file mode 100644
index 0000000000..f870d15082
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
@@ -0,0 +1,12 @@
+/* Linux/SPARC version.  This is the sigaction struction from the Linux
+   2.1.20 kernel.  */
+
+struct sigaction
+  {
+    __sighandler_t sa_handler;
+    sigset_t sa_mask;
+    unsigned long int sa_flags;
+    void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
+  };
+
+#define HAVE_SA_RESTORER
diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/kernel_stat.h
new file mode 100644
index 0000000000..993a8664dc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/kernel_stat.h
@@ -0,0 +1,21 @@
+/* Definition of `struct stat' used in the kernel */
+struct kernel_stat
+  {
+    unsigned short int st_dev;
+    unsigned long int st_ino;
+    unsigned short int st_mode;
+    short int st_nlink;
+    unsigned short int st_uid;
+    unsigned short int st_gid;
+    unsigned short int st_rdev;
+    long int st_size;
+    long int st_atime;
+    unsigned long int __unused1;
+    long int st_mtime;
+    unsigned long int __unused2;
+    long int st_ctime;
+    unsigned long int __unused3;
+    long int st_blksize;
+    long int st_blocks;
+    unsigned long int __unused4[2];
+  };
diff --git a/sysdeps/unix/sysv/linux/sparc/sigaction.h b/sysdeps/unix/sysv/linux/sparc/sigaction.h
new file mode 100644
index 0000000000..19aa7e39cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sigaction.h
@@ -0,0 +1,52 @@
+/* The proper definitions for Linux/SPARC sigaction.
+   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 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.  */
+
+/* Structure describing the action to be taken when a signal arrives.  */
+struct sigaction
+  {
+    /* Signal handler.  */
+    __sighandler_t sa_handler;
+
+    /* Additional set of signals to be blocked.  */
+    __sigset_t sa_mask;
+
+    /* Special flags.  */
+    unsigned int sa_flags;
+  };
+
+
+/* Bits in `sa_flags'.  */
+#define	SA_NOCLDSTOP 0x00000008	/* Don't send SIGCHLD when children stop.  */
+#ifdef __USE_MISC
+#define SA_STACK     0x00000001	/* Use signal stack by using `sa_restorer'.  */
+#define SA_RESTART   0x00000002	/* Don't restart syscall on signal return.  */
+#define SA_INTERRUPT 0x00000010	/* Historical no-op.  */
+#define SA_NOMASK    0x00000020	/* Don't automatically block the signal when
+				   its handler is being executed.  */
+#define SA_ONESHOT   0x00000004	/* Reset to SIG_DFL on entry to handler.  */
+
+/* Some aliases for the SA_ constants.  */
+#define SA_NODEFER	SA_NOMASK
+#define SA_RESETHAND	SA_ONESHOT
+#endif
+
+/* Values for the HOW argument to `sigprocmask'.  */
+#define	SIG_BLOCK	1	/* Block signals.  */
+#define	SIG_UNBLOCK	2	/* Unblock signals.  */
+#define	SIG_SETMASK	4	/* Set the set of blocked signals.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/signum.h b/sysdeps/unix/sysv/linux/sparc/signum.h
new file mode 100644
index 0000000000..d50a636bc3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/signum.h
@@ -0,0 +1,72 @@
+/* Signal number definitions.  Linux/SPARC version.
+   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 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.  */
+
+#ifdef	_SIGNAL_H
+
+/* Fake signal functions.  */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return.  */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action.  */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal.  */
+
+/*
+ * Linux/SPARC has different signal numbers that Linux/i386: I'm trying
+ * to make it OSF/1 binary compatible, at least for normal binaries.
+ */
+#define	_NSIG		32	/* Biggest signal number + 1.  */
+#define NSIG		_NSIG
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGEMT           7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGBUS          10
+#define SIGSEGV		11
+#define SIGSYS		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGURG          16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP		17
+#define SIGTSTP		18
+#define SIGCONT		19
+#define SIGCHLD		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGIO		23
+#define SIGPOLL		SIGIO   /* SysV name for SIGIO */
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGLOST		29
+#define SIGUSR1		30
+#define SIGUSR2		31
+
+/* Linux/SPARC does not have SIGPWR */
+#define SIGIOT          SIGABRT
+#endif	/* <signal.h> included.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/termbits.h b/sysdeps/unix/sysv/linux/sparc/termbits.h
new file mode 100644
index 0000000000..bf7aa1480f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/termbits.h
@@ -0,0 +1,217 @@
+/* termios type and macro definitions.  Linux/SPARC version.
+   Copyright (C) 1993, 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
+   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 _SPARC_TERMBITS_H
+#define _SPARC_TERMBITS_H	1
+
+typedef unsigned char   cc_t;
+typedef unsigned int    speed_t;
+typedef unsigned long   tcflag_t;
+
+#define NCCS 17
+struct termios
+  {
+    tcflag_t c_iflag;		/* input mode flags */
+    tcflag_t c_oflag;		/* output mode flags */
+    tcflag_t c_cflag;		/* control mode flags */
+    tcflag_t c_lflag;		/* local mode flags */
+    cc_t c_line;			/* line discipline */
+    cc_t c_cc[NCCS];		/* control characters */
+#ifdef __KERNEL__
+#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
+    cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
+#endif
+  };
+
+/* c_cc characters */
+#define VINTR    0
+#define VQUIT    1
+#define VERASE   2
+#define VKILL    3
+#define VEOF     4
+#define VEOL     5
+#define VEOL2    6
+#define VSWTC    7
+#define VSTART   8
+#define VSTOP    9
+
+
+
+#define VSUSP    10
+#define VDSUSP   11  /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+
+/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
+ * shared with eof/eol
+ */
+#ifdef __KERNEL__
+#define VMIN     16
+#define VTIME    17
+#else
+#define VMIN     VEOF
+#define VTIME    VEOL
+#endif
+
+/* c_iflag bits */
+#define IGNBRK	0x00000001
+#define BRKINT	0x00000002
+#define IGNPAR	0x00000004
+#define PARMRK	0x00000008
+#define INPCK	0x00000010
+#define ISTRIP	0x00000020
+#define INLCR	0x00000040
+#define IGNCR	0x00000080
+#define ICRNL	0x00000100
+#define IUCLC	0x00000200
+#define IXON	0x00000400
+#define IXANY	0x00000800
+#define IXOFF	0x00001000
+#define IMAXBEL	0x00002000
+
+/* c_oflag bits */
+#define OPOST	0x00000001
+#define OLCUC	0x00000002
+#define ONLCR	0x00000004
+#define OCRNL	0x00000008
+#define ONOCR	0x00000010
+#define ONLRET	0x00000020
+#define OFILL	0x00000040
+#define OFDEL	0x00000080
+#define NLDLY	0x00000100
+#define   NL0	0x00000000
+#define   NL1	0x00000100
+#define CRDLY	0x00000600
+#define   CR0	0x00000000
+#define   CR1	0x00000200
+#define   CR2	0x00000400
+#define   CR3	0x00000600
+#define TABDLY	0x00001800
+#define   TAB0	0x00000000
+#define   TAB1	0x00000800
+#define   TAB2	0x00001000
+#define   TAB3	0x00001800
+#define   XTABS	0x00001800
+#define BSDLY	0x00002000
+#define   BS0	0x00000000
+#define   BS1	0x00002000
+#define VTDLY	0x00004000
+#define   VT0	0x00000000
+#define   VT1	0x00004000
+#define FFDLY	0x00008000
+#define   FF0	0x00000000
+#define   FF1	0x00008000
+#define PAGEOUT 0x00010000  /* SUNOS specific */
+#define WRAP    0x00020000  /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD	0x0000000f
+#define  B0	0x00000000   /* hang up */
+#define  B50	0x00000001
+#define  B75	0x00000002
+#define  B110	0x00000003
+#define  B134	0x00000004
+#define  B150	0x00000005
+#define  B200	0x00000006
+#define  B300	0x00000007
+#define  B600	0x00000008
+#define  B1200	0x00000009
+#define  B1800	0x0000000a
+#define  B2400	0x0000000b
+#define  B4800	0x0000000c
+#define  B9600	0x0000000d
+#define  B19200	0x0000000e
+#define  B38400	0x0000000f
+#define EXTA    B19200
+#define EXTB    B38400
+#define  CSIZE  0x00000030
+#define   CS5	0x00000000
+#define   CS6	0x00000010
+#define   CS7	0x00000020
+#define   CS8	0x00000030
+#define CSTOPB	0x00000040
+#define CREAD	0x00000080
+#define PARENB	0x00000100
+#define PARODD	0x00000200
+#define HUPCL	0x00000400
+#define CLOCAL	0x00000800
+/* We'll never see these speeds with the Zilogs' but for completeness... */
+#define CBAUDEX 0x00010000
+#define  B57600  0x00010001
+#define  B115200 0x00010002
+#define  B230400 0x00010003
+#define  B460800 0x00010004
+#define CIBAUD	  0x000f0000  /* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  0x80000000  /* flow control */
+
+/* c_lflag bits */
+#define ISIG	0x00000001
+#define ICANON	0x00000002
+#define XCASE	0x00000004
+#define ECHO	0x00000008
+#define ECHOE	0x00000010
+#define ECHOK	0x00000020
+#define ECHONL	0x00000040
+#define NOFLSH	0x00000080
+#define TOSTOP	0x00000100
+#define ECHOCTL	0x00000200
+#define ECHOPRT	0x00000400
+#define ECHOKE	0x00000800
+#define DEFECHO 0x00001000  /* SUNOS thing, what is it? */
+#define FLUSHO	0x00002000
+#define PENDIN	0x00004000
+#define IEXTEN	0x00008000
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* !(_SPARC_TERMBITS_H) */