summary refs log tree commit diff
path: root/sysdeps/i386/fpu
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/i386/fpu')
-rw-r--r--sysdeps/i386/fpu/Implies2
-rw-r--r--sysdeps/i386/fpu/e_acos.S21
-rw-r--r--sysdeps/i386/fpu/e_acosf.S22
-rw-r--r--sysdeps/i386/fpu/e_acosh.S105
-rw-r--r--sysdeps/i386/fpu/e_acoshf.S105
-rw-r--r--sysdeps/i386/fpu/e_acoshl.S112
-rw-r--r--sysdeps/i386/fpu/e_acosl.S22
-rw-r--r--sysdeps/i386/fpu/e_asin.S20
-rw-r--r--sysdeps/i386/fpu/e_asinf.S21
-rw-r--r--sysdeps/i386/fpu/e_asinl.S22
-rw-r--r--sysdeps/i386/fpu/e_atan2.S15
-rw-r--r--sysdeps/i386/fpu/e_atan2f.S15
-rw-r--r--sysdeps/i386/fpu/e_atan2l.S17
-rw-r--r--sysdeps/i386/fpu/e_atanh.S101
-rw-r--r--sysdeps/i386/fpu/e_atanhf.S102
-rw-r--r--sysdeps/i386/fpu/e_atanhl.S108
-rw-r--r--sysdeps/i386/fpu/e_exp.S41
-rw-r--r--sysdeps/i386/fpu/e_exp10.S38
-rw-r--r--sysdeps/i386/fpu/e_exp10f.S38
-rw-r--r--sysdeps/i386/fpu/e_exp10l.S38
-rw-r--r--sysdeps/i386/fpu/e_expf.S42
-rw-r--r--sysdeps/i386/fpu/e_expl.S43
-rw-r--r--sysdeps/i386/fpu/e_fmod.S19
-rw-r--r--sysdeps/i386/fpu/e_fmodf.S20
-rw-r--r--sysdeps/i386/fpu/e_fmodl.S21
-rw-r--r--sysdeps/i386/fpu/e_hypot.S62
-rw-r--r--sysdeps/i386/fpu/e_hypotf.S62
-rw-r--r--sysdeps/i386/fpu/e_log.S59
-rw-r--r--sysdeps/i386/fpu/e_log10.S59
-rw-r--r--sysdeps/i386/fpu/e_log10f.S60
-rw-r--r--sysdeps/i386/fpu/e_log10l.S61
-rw-r--r--sysdeps/i386/fpu/e_logf.S60
-rw-r--r--sysdeps/i386/fpu/e_logl.S60
-rw-r--r--sysdeps/i386/fpu/e_pow.S320
-rw-r--r--sysdeps/i386/fpu/e_powf.S310
-rw-r--r--sysdeps/i386/fpu/e_powl.S307
-rw-r--r--sysdeps/i386/fpu/e_rem_pio2.c3
-rw-r--r--sysdeps/i386/fpu/e_rem_pio2f.c3
-rw-r--r--sysdeps/i386/fpu/e_rem_pio2l.c3
-rw-r--r--sysdeps/i386/fpu/e_remainder.S19
-rw-r--r--sysdeps/i386/fpu/e_remainderf.S19
-rw-r--r--sysdeps/i386/fpu/e_remainderl.S21
-rw-r--r--sysdeps/i386/fpu/e_scalb.S94
-rw-r--r--sysdeps/i386/fpu/e_scalbf.S96
-rw-r--r--sysdeps/i386/fpu/e_scalbl.S96
-rw-r--r--sysdeps/i386/fpu/e_sqrt.S14
-rw-r--r--sysdeps/i386/fpu/e_sqrtf.S14
-rw-r--r--sysdeps/i386/fpu/e_sqrtl.S16
-rw-r--r--sysdeps/i386/fpu/k_rem_pio2.c3
-rw-r--r--sysdeps/i386/fpu/k_rem_pio2f.c3
-rw-r--r--sysdeps/i386/fpu/k_rem_pio2l.c3
-rw-r--r--sysdeps/i386/fpu/s_asinh.S139
-rw-r--r--sysdeps/i386/fpu/s_asinhf.S139
-rw-r--r--sysdeps/i386/fpu/s_asinhl.S147
-rw-r--r--sysdeps/i386/fpu/s_atan.S16
-rw-r--r--sysdeps/i386/fpu/s_atanf.S16
-rw-r--r--sysdeps/i386/fpu/s_atanl.S18
-rw-r--r--sysdeps/i386/fpu/s_cbrt.S201
-rw-r--r--sysdeps/i386/fpu/s_cbrtf.S178
-rw-r--r--sysdeps/i386/fpu/s_cbrtl.S229
-rw-r--r--sysdeps/i386/fpu/s_ceil.S32
-rw-r--r--sysdeps/i386/fpu/s_ceilf.S32
-rw-r--r--sysdeps/i386/fpu/s_ceill.S33
-rw-r--r--sysdeps/i386/fpu/s_cexp.S259
-rw-r--r--sysdeps/i386/fpu/s_cexpf.S255
-rw-r--r--sysdeps/i386/fpu/s_cexpl.S262
-rw-r--r--sysdeps/i386/fpu/s_copysign.S20
-rw-r--r--sysdeps/i386/fpu/s_copysignf.S20
-rw-r--r--sysdeps/i386/fpu/s_copysignl.S21
-rw-r--r--sysdeps/i386/fpu/s_cos.S29
-rw-r--r--sysdeps/i386/fpu/s_cosf.S16
-rw-r--r--sysdeps/i386/fpu/s_cosl.S31
-rw-r--r--sysdeps/i386/fpu/s_exp2.S37
-rw-r--r--sysdeps/i386/fpu/s_exp2f.S37
-rw-r--r--sysdeps/i386/fpu/s_exp2l.S37
-rw-r--r--sysdeps/i386/fpu/s_expm1.S88
-rw-r--r--sysdeps/i386/fpu/s_expm1f.S88
-rw-r--r--sysdeps/i386/fpu/s_expm1l.S88
-rw-r--r--sysdeps/i386/fpu/s_fdim.S51
-rw-r--r--sysdeps/i386/fpu/s_fdimf.S51
-rw-r--r--sysdeps/i386/fpu/s_fdiml.S51
-rw-r--r--sysdeps/i386/fpu/s_finite.S15
-rw-r--r--sysdeps/i386/fpu/s_finitef.S15
-rw-r--r--sysdeps/i386/fpu/s_finitel.S14
-rw-r--r--sysdeps/i386/fpu/s_floor.S32
-rw-r--r--sysdeps/i386/fpu/s_floorf.S32
-rw-r--r--sysdeps/i386/fpu/s_floorl.S33
-rw-r--r--sysdeps/i386/fpu/s_fma.S31
-rw-r--r--sysdeps/i386/fpu/s_fmaf.S31
-rw-r--r--sysdeps/i386/fpu/s_fmal.S32
-rw-r--r--sysdeps/i386/fpu/s_fmax.S44
-rw-r--r--sysdeps/i386/fpu/s_fmaxf.S44
-rw-r--r--sysdeps/i386/fpu/s_fmaxl.S44
-rw-r--r--sysdeps/i386/fpu/s_fmin.S44
-rw-r--r--sysdeps/i386/fpu/s_fminf.S44
-rw-r--r--sysdeps/i386/fpu/s_fminl.S44
-rw-r--r--sysdeps/i386/fpu/s_frexp.S82
-rw-r--r--sysdeps/i386/fpu/s_frexpf.S80
-rw-r--r--sysdeps/i386/fpu/s_frexpl.S82
-rw-r--r--sysdeps/i386/fpu/s_ilogb.S22
-rw-r--r--sysdeps/i386/fpu/s_ilogbf.S22
-rw-r--r--sysdeps/i386/fpu/s_ilogbl.S23
-rw-r--r--sysdeps/i386/fpu/s_isinfl.c36
-rw-r--r--sysdeps/i386/fpu/s_isnanl.c47
-rw-r--r--sysdeps/i386/fpu/s_llrint.S34
-rw-r--r--sysdeps/i386/fpu/s_llrintf.S34
-rw-r--r--sysdeps/i386/fpu/s_llrintl.S34
-rw-r--r--sysdeps/i386/fpu/s_log1p.S62
-rw-r--r--sysdeps/i386/fpu/s_log1pf.S62
-rw-r--r--sysdeps/i386/fpu/s_log1pl.S68
-rw-r--r--sysdeps/i386/fpu/s_log2.S59
-rw-r--r--sysdeps/i386/fpu/s_log2f.S59
-rw-r--r--sysdeps/i386/fpu/s_log2l.S59
-rw-r--r--sysdeps/i386/fpu/s_logb.S16
-rw-r--r--sysdeps/i386/fpu/s_logbf.S16
-rw-r--r--sysdeps/i386/fpu/s_logbl.S17
-rw-r--r--sysdeps/i386/fpu/s_lrint.S33
-rw-r--r--sysdeps/i386/fpu/s_lrintf.S33
-rw-r--r--sysdeps/i386/fpu/s_lrintl.S33
-rw-r--r--sysdeps/i386/fpu/s_nearbyint.S25
-rw-r--r--sysdeps/i386/fpu/s_nearbyintf.S25
-rw-r--r--sysdeps/i386/fpu/s_nearbyintl.S25
-rw-r--r--sysdeps/i386/fpu/s_nextafterl.c102
-rw-r--r--sysdeps/i386/fpu/s_remquo.S36
-rw-r--r--sysdeps/i386/fpu/s_remquof.S36
-rw-r--r--sysdeps/i386/fpu/s_remquol.S36
-rw-r--r--sysdeps/i386/fpu/s_rint.S15
-rw-r--r--sysdeps/i386/fpu/s_rintf.S15
-rw-r--r--sysdeps/i386/fpu/s_rintl.S16
-rw-r--r--sysdeps/i386/fpu/s_scalbln.c2
-rw-r--r--sysdeps/i386/fpu/s_scalblnf.c2
-rw-r--r--sysdeps/i386/fpu/s_scalblnl.c2
-rw-r--r--sysdeps/i386/fpu/s_scalbn.S19
-rw-r--r--sysdeps/i386/fpu/s_scalbnf.S19
-rw-r--r--sysdeps/i386/fpu/s_scalbnl.S20
-rw-r--r--sysdeps/i386/fpu/s_significand.S16
-rw-r--r--sysdeps/i386/fpu/s_significandf.S16
-rw-r--r--sysdeps/i386/fpu/s_significandl.S17
-rw-r--r--sysdeps/i386/fpu/s_sin.S29
-rw-r--r--sysdeps/i386/fpu/s_sincos.S48
-rw-r--r--sysdeps/i386/fpu/s_sincosf.S48
-rw-r--r--sysdeps/i386/fpu/s_sincosl.S48
-rw-r--r--sysdeps/i386/fpu/s_sinf.S16
-rw-r--r--sysdeps/i386/fpu/s_sinl.S31
-rw-r--r--sysdeps/i386/fpu/s_tan.S30
-rw-r--r--sysdeps/i386/fpu/s_tanf.S17
-rw-r--r--sysdeps/i386/fpu/s_tanl.S32
-rw-r--r--sysdeps/i386/fpu/s_trunc.S36
-rw-r--r--sysdeps/i386/fpu/s_truncf.S36
-rw-r--r--sysdeps/i386/fpu/s_truncl.S36
-rw-r--r--sysdeps/i386/fpu/t_exp.c1
151 files changed, 7920 insertions, 2 deletions
diff --git a/sysdeps/i386/fpu/Implies b/sysdeps/i386/fpu/Implies
deleted file mode 100644
index de9b0b27aa..0000000000
--- a/sysdeps/i386/fpu/Implies
+++ /dev/null
@@ -1,2 +0,0 @@
-# For x86 machines with FPU, use the i387 port of libm by JT Conklin.
-libm-i387
diff --git a/sysdeps/i386/fpu/e_acos.S b/sysdeps/i386/fpu/e_acos.S
new file mode 100644
index 0000000000..b9d07b1091
--- /dev/null
+++ b/sysdeps/i386/fpu/e_acos.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+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 */
+	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/i386/fpu/e_acosf.S b/sysdeps/i386/fpu/e_acosf.S
new file mode 100644
index 0000000000..50b13fd1bd
--- /dev/null
+++ b/sysdeps/i386/fpu/e_acosf.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* acos = atan (sqrt(1 - x^2) / x) */
+ENTRY(__ieee754_acosf)
+	flds	4(%esp)			/* x */
+	fld	%st
+	fmul	%st(0)			/* x^2 */
+	fld1
+	fsubp				/* 1 - x^2 */
+	fsqrt				/* sqrt (1 - x^2) */
+	fxch	%st(1)
+	fpatan
+	ret
+END (__ieee754_acosf)
diff --git a/sysdeps/i386/fpu/e_acosh.S b/sysdeps/i386/fpu/e_acosh.S
new file mode 100644
index 0000000000..a3397b365c
--- /dev/null
+++ b/sysdeps/i386/fpu/e_acosh.S
@@ -0,0 +1,105 @@
+/* ix87 specific implementation of arcsinh.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	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)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_acosh)
+	movl	8(%esp), %ecx
+	cmpl	$0x3ff00000, %ecx
+	jl	5f			// < 1 => invalid
+	fldln2				// log(2)
+	fldl	4(%esp)			// x : log(2)
+	cmpl	$0x41b00000, %ecx
+	ja	3f			// x > 2^28
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpl	$0x40000000, %ecx
+	ja	4f			// x > 2
+
+	// 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+	fsubl	MO(one)			// x-1 : log(2)
+	fld	%st			// x-1 : x-1 : log(2)
+	fmul	%st(1)			// (x-1)^2 : x-1 : log(2)
+	fadd	%st(1)			// x-1+(x-1)^2 : x-1 : log(2)
+	fadd	%st(1)			// 2*(x-1)+(x-1)^2 : x-1 : log(2)
+	fsqrt				// sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
+	faddp				// x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
+	fcoml	MO(limit)
+	fnstsw
+	sahf
+	ja	2f
+	fyl2xp1				// log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+	ret
+
+2:	faddl	MO(one)			// x+sqrt(2*(x-1)+(x-1)^2) : log(2)
+	fyl2x				// log(x+sqrt(2*(x-1)+(x-1)^2))
+	ret
+
+	// x > 2^28 => y = log(x) + log(2)
+	.align ALIGNARG(4)
+3:	fyl2x				// log(x)
+	fldln2				// log(2) : log(x)
+	faddp				// log(x)+log(2)
+	ret
+
+	// 2^28 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
+	.align ALIGNARG(4)
+4:	fld	%st			// x : x : log(2)
+	fadd	%st, %st(1)		// x : 2*x : log(2)
+	fld	%st			// x : x : 2*x : log(2)
+	fmul	%st(1)			// x^2 : x : 2*x : log(2)
+	fsubl	MO(one)			// x^2-1 : x : 2*x : log(2)
+	fsqrt				// sqrt(x^2-1) : x : 2*x : log(2)
+	faddp				// x+sqrt(x^2-1) : 2*x : log(2)
+	fdivrl	MO(one)			// 1/(x+sqrt(x^2-1)) : 2*x : log(2)
+	fsubrp				// 2*x+1/(x+sqrt(x^2)-1) : log(2)
+	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
+	ret
+
+	// x < 1 => NaN
+	.align ALIGNARG(4)
+5:	fldz
+	fdiv	%st, %st(0)
+	ret
+END(__ieee754_acosh)
diff --git a/sysdeps/i386/fpu/e_acoshf.S b/sysdeps/i386/fpu/e_acoshf.S
new file mode 100644
index 0000000000..8aa78957e2
--- /dev/null
+++ b/sysdeps/i386/fpu/e_acoshf.S
@@ -0,0 +1,105 @@
+/* ix87 specific implementation of arcsinh.
+   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.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	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)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_acoshf)
+	movl	4(%esp), %ecx
+	cmpl	$0x3f800000, %ecx
+	jl	5f			// < 1 => invalid
+	fldln2				// log(2)
+	flds	4(%esp)			// x : log(2)
+	cmpl	$0x47000000, %ecx
+	ja	3f			// x > 2^14
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpl	$0x40000000, %ecx
+	ja	4f			// x > 2
+
+	// 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+	fsubl	MO(one)			// x-1 : log(2)
+	fld	%st			// x-1 : x-1 : log(2)
+	fmul	%st(1)			// (x-1)^2 : x-1 : log(2)
+	fadd	%st(1)			// x-1+(x-1)^2 : x-1 : log(2)
+	fadd	%st(1)			// 2*(x-1)+(x-1)^2 : x-1 : log(2)
+	fsqrt				// sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
+	faddp				// x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
+	fcoml	MO(limit)
+	fnstsw
+	sahf
+	ja	2f
+	fyl2xp1				// log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+	ret
+
+2:	faddl	MO(one)			// x+sqrt(2*(x-1)+(x-1)^2) : log(2)
+	fyl2x				// log(x+sqrt(2*(x-1)+(x-1)^2))
+	ret
+
+	// x > 2^14 => y = log(x) + log(2)
+	.align ALIGNARG(4)
+3:	fyl2x				// log(x)
+	fldln2				// log(2) : log(x)
+	faddp				// log(x)+log(2)
+	ret
+
+	// 2^28 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
+	.align ALIGNARG(4)
+4:	fld	%st			// x : x : log(2)
+	fadd	%st, %st(1)		// x : 2*x : log(2)
+	fld	%st			// x : x : 2*x : log(2)
+	fmul	%st(1)			// x^2 : x : 2*x : log(2)
+	fsubl	MO(one)			// x^2-1 : x : 2*x : log(2)
+	fsqrt				// sqrt(x^2-1) : x : 2*x : log(2)
+	faddp				// x+sqrt(x^2-1) : 2*x : log(2)
+	fdivrl	MO(one)			// 1/(x+sqrt(x^2-1)) : 2*x : log(2)
+	fsubrp				// 2*x+1/(x+sqrt(x^2)-1) : log(2)
+	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
+	ret
+
+	// x < 1 => NaN
+	.align ALIGNARG(4)
+5:	fldz
+	fdiv	%st, %st(0)
+	ret
+END(__ieee754_acoshf)
diff --git a/sysdeps/i386/fpu/e_acoshl.S b/sysdeps/i386/fpu/e_acoshl.S
new file mode 100644
index 0000000000..0c81daaebe
--- /dev/null
+++ b/sysdeps/i386/fpu/e_acoshl.S
@@ -0,0 +1,112 @@
+/* ix87 specific implementation of arcsinh.
+   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.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	/* Please note that we use double value for 1.0.  This number
+	   has an exact representation and so we don't get accuracy
+	   problems.  The advantage is that the code is simpler.  */
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_acoshl)
+	movl	12(%esp), %ecx
+	andl	$0xffff, %ecx
+	cmpl	$0x3fff, %ecx
+	jl	5f			// < 1 => invalid
+	fldln2				// log(2)
+	fldt	4(%esp)			// x : log(2)
+	cmpl	$0x4020, %ecx
+	ja	3f			// x > 2^34
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpl	$0x4000, %ecx
+	ja	4f			// x > 2
+
+	// 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+	fsubl	MO(one)			// x-1 : log(2)
+	fld	%st			// x-1 : x-1 : log(2)
+	fmul	%st(1)			// (x-1)^2 : x-1 : log(2)
+	fadd	%st(1)			// x-1+(x-1)^2 : x-1 : log(2)
+	fadd	%st(1)			// 2*(x-1)+(x-1)^2 : x-1 : log(2)
+	fsqrt				// sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
+	faddp				// x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
+	fcoml	MO(limit)
+	fnstsw
+	sahf
+	ja	2f
+	fyl2xp1				// log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+	ret
+
+2:	faddl	MO(one)			// x+sqrt(2*(x-1)+(x-1)^2) : log(2)
+	fyl2x				// log(x+sqrt(2*(x-1)+(x-1)^2))
+	ret
+
+	// x > 2^34 => y = log(x) + log(2)
+	.align ALIGNARG(4)
+3:	fyl2x				// log(x)
+	fldln2				// log(2) : log(x)
+	faddp				// log(x)+log(2)
+	ret
+
+	// 2^34 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
+	.align ALIGNARG(4)
+4:	fld	%st			// x : x : log(2)
+	fadd	%st, %st(1)		// x : 2*x : log(2)
+	fld	%st			// x : x : 2*x : log(2)
+	fmul	%st(1)			// x^2 : x : 2*x : log(2)
+	fsubl	MO(one)			// x^2-1 : x : 2*x : log(2)
+	fsqrt				// sqrt(x^2-1) : x : 2*x : log(2)
+	faddp				// x+sqrt(x^2-1) : 2*x : log(2)
+	fdivrl	MO(one)			// 1/(x+sqrt(x^2-1)) : 2*x : log(2)
+	fsubrp				// 2*x+1/(x+sqrt(x^2)-1) : log(2)
+	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
+	ret
+
+	// x < 1 => NaN
+	.align ALIGNARG(4)
+5:	fldz
+	fdiv	%st, %st(0)
+	ret
+END(__ieee754_acoshl)
diff --git a/sysdeps/i386/fpu/e_acosl.S b/sysdeps/i386/fpu/e_acosl.S
new file mode 100644
index 0000000000..d69f056556
--- /dev/null
+++ b/sysdeps/i386/fpu/e_acosl.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+
+/* acosl = atanl (sqrtl(1 - x^2) / x) */
+ENTRY(__ieee754_acosl)
+	fldt	4(%esp)			/* x */
+	fld	%st
+	fmul	%st(0)			/* x^2 */
+	fld1
+	fsubp				/* 1 - x^2 */
+	fsqrt				/* sqrtl (1 - x^2) */
+	fxch	%st(1)
+	fpatan
+	ret
+END (__ieee754_acosl)
diff --git a/sysdeps/i386/fpu/e_asin.S b/sysdeps/i386/fpu/e_asin.S
new file mode 100644
index 0000000000..945e308245
--- /dev/null
+++ b/sysdeps/i386/fpu/e_asin.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+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 */
+	fld	%st
+	fmul	%st(0)			/* x^2 */
+	fld1
+	fsubp				/* 1 - x^2 */
+	fsqrt				/* sqrt (1 - x^2) */
+	fpatan
+	ret
+END (__ieee754_asin)
diff --git a/sysdeps/i386/fpu/e_asinf.S b/sysdeps/i386/fpu/e_asinf.S
new file mode 100644
index 0000000000..d450e9a740
--- /dev/null
+++ b/sysdeps/i386/fpu/e_asinf.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* asin = atan (x / sqrt(1 - x^2)) */
+ENTRY(__ieee754_asinf)
+	flds	4(%esp)			/* x */
+	fld	%st
+	fmul	%st(0)			/* x^2 */
+	fld1
+	fsubp				/* 1 - x^2 */
+	fsqrt				/* sqrt (1 - x^2) */
+	fpatan
+	ret
+END (__ieee754_asinf)
diff --git a/sysdeps/i386/fpu/e_asinl.S b/sysdeps/i386/fpu/e_asinl.S
new file mode 100644
index 0000000000..3919fbcf58
--- /dev/null
+++ b/sysdeps/i386/fpu/e_asinl.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* asinl = atanl (x / sqrtl(1 - x^2)) */
+ENTRY(__ieee754_asinl)
+	fldt	4(%esp)			/* x */
+	fld	%st
+	fmul	%st(0)			/* x^2 */
+	fld1
+	fsubp				/* 1 - x^2 */
+	fsqrt				/* sqrt (1 - x^2) */
+	fpatan
+	ret
+END (__ieee754_asinl)
diff --git a/sysdeps/i386/fpu/e_atan2.S b/sysdeps/i386/fpu/e_atan2.S
new file mode 100644
index 0000000000..8df04e485e
--- /dev/null
+++ b/sysdeps/i386/fpu/e_atan2.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_atan2.S,v 1.4 1995/05/08 23:46:28 jtc Exp $")
+
+ENTRY(__ieee754_atan2)
+	fldl	 4(%esp)
+	fldl	12(%esp)
+	fpatan
+	ret
+END (__ieee754_atan2)
diff --git a/sysdeps/i386/fpu/e_atan2f.S b/sysdeps/i386/fpu/e_atan2f.S
new file mode 100644
index 0000000000..fc6621f183
--- /dev/null
+++ b/sysdeps/i386/fpu/e_atan2f.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_atan2f.S,v 1.1 1995/05/08 23:35:10 jtc Exp $")
+
+ENTRY(__ieee754_atan2f)
+	flds	4(%esp)
+	flds	8(%esp)
+	fpatan
+	ret
+END (__ieee754_atan2f)
diff --git a/sysdeps/i386/fpu/e_atan2l.S b/sysdeps/i386/fpu/e_atan2l.S
new file mode 100644
index 0000000000..f58eaa94a9
--- /dev/null
+++ b/sysdeps/i386/fpu/e_atan2l.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_atan2l)
+	fldt	 4(%esp)
+	fldt	16(%esp)
+	fpatan
+	ret
+END (__ieee754_atan2l)
diff --git a/sysdeps/i386/fpu/e_atanh.S b/sysdeps/i386/fpu/e_atanh.S
new file mode 100644
index 0000000000..231e96f57f
--- /dev/null
+++ b/sysdeps/i386/fpu/e_atanh.S
@@ -0,0 +1,101 @@
+/* ix87 specific implementation of arctanh function.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(half,@object)
+half:	.double 0.5
+	ASM_SIZE_DIRECTIVE(half)
+	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(ln2_2,@object)
+ln2_2:	.tfloat 0.3465735902799726547086160
+	ASM_SIZE_DIRECTIVE(ln2_2)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_atanh)
+	movl	8(%esp), %ecx
+
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+	andl	$0x80000000, %ecx // ECX == 0 iff X >= 0
+
+	fldt	MO(ln2_2)	// 0.5*ln2
+	xorl	%ecx, 8(%esp)
+	fldl	4(%esp)		// |x| : 0.5*ln2
+	fcoml	MO(half)	// |x| : 0.5*ln2
+	fld	%st		// |x| : |x| : 0.5*ln2
+	fnstsw			// |x| : |x| : 0.5*ln2
+	sahf
+	jae	2f
+	fadd	%st, %st(1)	// |x| : 2*|x| : 0.5*ln2
+	fld	%st		// |x| : |x| : 2*|x| : 0.5*ln2
+	fsubrl	MO(one)		// 1-|x| : |x| : 2*|x| : 0.5*ln2
+	fxch			// |x| : 1-|x| : 2*|x| : 0.5*ln2
+	fmul	%st(2)		// 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
+	fdivp			// (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
+	faddp			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fcoml	MO(limit)	// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fnstsw			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	sahf
+	jae	4f
+	fyl2xp1			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3:	ret
+
+	.align ALIGNARG(4)
+4:	faddl	MO(one)		// 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fyl2x			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3:	ret
+
+	.align ALIGNARG(4)
+2:	faddl	MO(one)		// 1+|x| : |x| : 0.5*ln2
+	fxch			// |x| : 1+|x| : 0.5*ln2
+	fsubrl	MO(one)		// 1-|x| : 1+|x| : 0.5*ln2
+	fdivrp			// (1+|x|)/(1-|x|) : 0.5*ln2
+	fyl2x			// 0.5*ln2*ld((1+|x|)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld((1+x)/(1-x))
+3:	ret
+END(__ieee754_atanh)
diff --git a/sysdeps/i386/fpu/e_atanhf.S b/sysdeps/i386/fpu/e_atanhf.S
new file mode 100644
index 0000000000..687d4c97fb
--- /dev/null
+++ b/sysdeps/i386/fpu/e_atanhf.S
@@ -0,0 +1,102 @@
+/* ix87 specific implementation of arctanh function.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(half,@object)
+half:	.double 0.5
+	ASM_SIZE_DIRECTIVE(half)
+	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)
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(ln2_2,@object)
+ln2_2:	.tfloat 0.3465735902799726547086160
+	ASM_SIZE_DIRECTIVE(ln2_2)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_atanhf)
+	movl	4(%esp), %ecx
+
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+	andl	$0x80000000, %ecx // ECX == 0 iff X >= 0
+
+	fldt	MO(ln2_2)	// 0.5*ln2
+	xorl	%ecx, 4(%esp)
+	flds	4(%esp)		// |x| : 0.5*ln2
+	fcoml	MO(half)	// |x| : 0.5*ln2
+	fld	%st(0)		// |x| : |x| : 0.5*ln2
+	fnstsw			// |x| : |x| : 0.5*ln2
+	sahf
+	jae	2f
+	fadd	%st, %st(1)	// |x| : 2*|x| : 0.5*ln2
+	fld	%st		// |x| : |x| : 2*|x| : 0.5*ln2
+	fsubrl	MO(one)		// 1-|x| : |x| : 2*|x| : 0.5*ln2
+	fxch			// |x| : 1-|x| : 2*|x| : 0.5*ln2
+	fmul	%st(2)		// 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
+	fdivp			// (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
+	faddp			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fcoml	MO(limit)	// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fnstsw			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	sahf
+	jae	4f
+	fyl2xp1			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3:	ret
+
+	.align ALIGNARG(4)
+4:	faddl	MO(one)		// 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fyl2x			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3:	ret
+
+	.align ALIGNARG(4)
+2:	faddl	MO(one)		// 1+|x| : |x| : 0.5*ln2
+	fxch			// |x| : 1+|x| : 0.5*ln2
+	fsubrl	MO(one)		// 1-|x| : 1+|x| : 0.5*ln2
+	fdivrp			// (1+|x|)/(1-|x|) : 0.5*ln2
+	fyl2x			// 0.5*ln2*ld((1+|x|)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld((1+x)/(1-x))
+3:	ret
+END(__ieee754_atanhf)
diff --git a/sysdeps/i386/fpu/e_atanhl.S b/sysdeps/i386/fpu/e_atanhl.S
new file mode 100644
index 0000000000..8a2bd11ce4
--- /dev/null
+++ b/sysdeps/i386/fpu/e_atanhl.S
@@ -0,0 +1,108 @@
+/* ix87 specific implementation of arctanh function.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	/* Please note that we use double values for 0.5 and 1.0.  These
+	   numbers have exact representations and so we don't get accuracy
+	   problems.  The advantage is that the code is simpler.  */
+	ASM_TYPE_DIRECTIVE(half,@object)
+half:	.double 0.5
+	ASM_SIZE_DIRECTIVE(half)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(ln2_2,@object)
+ln2_2:	.tfloat 0.3465735902799726547086160
+	ASM_SIZE_DIRECTIVE(ln2_2)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_atanhl)
+	movl	12(%esp), %ecx
+
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+	andl	$0x8000, %ecx	// ECX == 0 iff X >= 0
+
+	fldt	MO(ln2_2)	// 0.5*ln2
+	xorl	%ecx, 12(%esp)
+	fldt	4(%esp)		// |x| : 0.5*ln2
+	fcoml	MO(half)	// |x| : 0.5*ln2
+	fld	%st(0)		// |x| : |x| : 0.5*ln2
+	fnstsw			// |x| : |x| : 0.5*ln2
+	sahf
+	jae	2f
+	fadd	%st, %st(1)	// |x| : 2*|x| : 0.5*ln2
+	fld	%st		// |x| : |x| : 2*|x| : 0.5*ln2
+	fsubrl	MO(one)		// 1-|x| : |x| : 2*|x| : 0.5*ln2
+	fxch			// |x| : 1-|x| : 2*|x| : 0.5*ln2
+	fmul	%st(2)		// 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
+	fdivp			// (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
+	faddp			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fcoml	MO(limit)	// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fnstsw			// 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	sahf
+	jae	4f
+	fyl2xp1			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3:	ret
+
+	.align ALIGNARG(4)
+4:	faddl	MO(one)		// 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+	fyl2x			// 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3:	ret
+
+	.align ALIGNARG(4)
+2:	faddl	MO(one)		// 1+|x| : |x| : 0.5*ln2
+	fxch			// |x| : 1+|x| : 0.5*ln2
+	fsubrl	MO(one)		// 1-|x| : 1+|x| : 0.5*ln2
+	fdivrp			// (1+|x|)/(1-|x|) : 0.5*ln2
+	fyl2x			// 0.5*ln2*ld((1+|x|)/(1-|x|))
+	jecxz	3f
+	fchs			// 0.5*ln2*ld((1+x)/(1-x))
+3:	ret
+END(__ieee754_atanhl)
diff --git a/sysdeps/i386/fpu/e_exp.S b/sysdeps/i386/fpu/e_exp.S
new file mode 100644
index 0000000000..4a75fa1d1c
--- /dev/null
+++ b/sysdeps/i386/fpu/e_exp.S
@@ -0,0 +1,41 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_exp.S,v 1.7 1996/07/03 17:31:28 jtc Exp $")
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_exp)
+	fldl	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fldl2e
+	fmulp				/* x * log2(e) */
+	fld	%st
+	frndint				/* int(x * log2(e)) */
+	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
+	fxch
+	f2xm1				/* 2^(fract(x * log2(e))) - 1 */
+	fld1
+	faddp				/* 2^(fract(x * log2(e))) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+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/i386/fpu/e_exp10.S b/sysdeps/i386/fpu/e_exp10.S
new file mode 100644
index 0000000000..6bfcdbb723
--- /dev/null
+++ b/sysdeps/i386/fpu/e_exp10.S
@@ -0,0 +1,38 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+/* 10^x = 2^(x * log2(10)) */
+ENTRY(__ieee754_exp10)
+	fldl	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fldl2t
+	fmulp				/* x * log2(10) */
+	fld	%st
+	frndint				/* int(x * log2(10)) */
+	fsubr	%st,%st(1)		/* fract(x * log2(10)) */
+	fxch
+	f2xm1				/* 2^(fract(x * log2(10))) - 1 */
+	fld1
+	faddp				/* 2^(fract(x * log2(10))) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+1:	testl	$0x200, %eax		/* Test sign.  */
+	jz	2f			/* If positive, jump.  */
+	fstp	%st
+	fldz				/* Set result to 0.  */
+2:	ret
+END (__ieee754_exp10)
diff --git a/sysdeps/i386/fpu/e_exp10f.S b/sysdeps/i386/fpu/e_exp10f.S
new file mode 100644
index 0000000000..4791b99afa
--- /dev/null
+++ b/sysdeps/i386/fpu/e_exp10f.S
@@ -0,0 +1,38 @@
+/*
+ * Written by Ulrich Drepper.
+ */
+
+#include <machine/asm.h>
+
+/* e^x = 2^(x * log2(10)) */
+ENTRY(__ieee754_exp10f)
+	flds	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fldl2t
+	fmulp				/* x * log2(10) */
+	fld	%st
+	frndint				/* int(x * log2(10)) */
+	fsubr	%st,%st(1)		/* fract(x * log2(10)) */
+	fxch
+	f2xm1				/* 2^(fract(x * log2(10))) - 1 */
+	fld1
+	faddp				/* 2^(fract(x * log2(10))) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+1:	testl	$0x200, %eax		/* Test sign.  */
+	jz	2f			/* If positive, jump.  */
+	fstp	%st
+	fldz				/* Set result to 0.  */
+2:	ret
+END (__ieee754_exp10f)
diff --git a/sysdeps/i386/fpu/e_exp10l.S b/sysdeps/i386/fpu/e_exp10l.S
new file mode 100644
index 0000000000..71f0da792d
--- /dev/null
+++ b/sysdeps/i386/fpu/e_exp10l.S
@@ -0,0 +1,38 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+/* e^x = 2^(x * log2l(10)) */
+ENTRY(__ieee754_exp10l)
+	fldt	4(%esp)
+/* I added the following ugly construct because expl(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fldl2t
+	fmulp				/* x * log2(10) */
+	fld	%st
+	frndint				/* int(x * log2(10)) */
+	fsubr	%st,%st(1)		/* fract(x * log2(10)) */
+	fxch
+	f2xm1				/* 2^(fract(x * log2(10))) - 1 */
+	fld1
+	faddp				/* 2^(fract(x * log2(10))) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+1:	testl	$0x200, %eax		/* Test sign.  */
+	jz	2f			/* If positive, jump.  */
+	fstp	%st
+	fldz				/* Set result to 0.  */
+2:	ret
+END (__ieee754_exp10l)
diff --git a/sysdeps/i386/fpu/e_expf.S b/sysdeps/i386/fpu/e_expf.S
new file mode 100644
index 0000000000..5fd49b89fd
--- /dev/null
+++ b/sysdeps/i386/fpu/e_expf.S
@@ -0,0 +1,42 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_expf)
+	flds	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fldl2e
+	fmulp				/* x * log2(e) */
+	fld	%st
+	frndint				/* int(x * log2(e)) */
+	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
+	fxch
+	f2xm1				/* 2^(fract(x * log2(e))) - 1 */
+	fld1
+	faddp				/* 2^(fract(x * log2(e))) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+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/i386/fpu/e_expl.S b/sysdeps/i386/fpu/e_expl.S
new file mode 100644
index 0000000000..2bcdf58c58
--- /dev/null
+++ b/sysdeps/i386/fpu/e_expl.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* e^x = 2^(x * log2l(e)) */
+ENTRY(__ieee754_expl)
+	fldt	4(%esp)
+/* I added the following ugly construct because expl(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fldl2e
+	fmulp				/* x * log2(e) */
+	fld	%st
+	frndint				/* int(x * log2(e)) */
+	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
+	fxch
+	f2xm1				/* 2^(fract(x * log2(e))) - 1 */
+	fld1
+	faddp				/* 2^(fract(x * log2(e))) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+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/i386/fpu/e_fmod.S b/sysdeps/i386/fpu/e_fmod.S
new file mode 100644
index 0000000000..4cf6e92054
--- /dev/null
+++ b/sysdeps/i386/fpu/e_fmod.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_fmod.S,v 1.4 1995/05/08 23:47:56 jtc Exp $")
+
+ENTRY(__ieee754_fmod)
+	fldl	12(%esp)
+	fldl	4(%esp)
+1:	fprem
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	ret
+END (__ieee754_fmod)
diff --git a/sysdeps/i386/fpu/e_fmodf.S b/sysdeps/i386/fpu/e_fmodf.S
new file mode 100644
index 0000000000..bbce40976d
--- /dev/null
+++ b/sysdeps/i386/fpu/e_fmodf.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_fmodf)
+	flds	8(%esp)
+	flds	4(%esp)
+1:	fprem
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	ret
+END(__ieee754_fmodf)
diff --git a/sysdeps/i386/fpu/e_fmodl.S b/sysdeps/i386/fpu/e_fmodl.S
new file mode 100644
index 0000000000..7ae63a40ab
--- /dev/null
+++ b/sysdeps/i386/fpu/e_fmodl.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_fmodl)
+	fldt	16(%esp)
+	fldt	4(%esp)
+1:	fprem
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	ret
+END (__ieee754_fmodl)
diff --git a/sysdeps/i386/fpu/e_hypot.S b/sysdeps/i386/fpu/e_hypot.S
new file mode 100644
index 0000000000..07a32878a0
--- /dev/null
+++ b/sysdeps/i386/fpu/e_hypot.S
@@ -0,0 +1,62 @@
+/* Compute the hypothenuse of X and Y.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   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>
+
+	.text
+ENTRY(__ieee754_hypot)
+	fldl	4(%esp)		// x
+	fxam
+	fnstsw
+	fldl	12(%esp)	// y : x
+	movb	%ah, %ch
+	fxam
+	fnstsw
+	movb	%ah, %al
+	orb	%ch, %ah
+	sahf
+	jc	1f
+	fmul	%st(0)		// y * y : x
+	fxch			// x : y * y
+	fmul	%st(0)		// x * x : y * y
+	faddp			// x * x + y * y
+	fsqrt
+2:	ret
+
+	// We have to test whether any of the parameters is Inf.
+	// In this case the result is infinity.
+1:	andb	$0x45, %al
+	cmpb	$5, %al
+	je	3f		// jump if y is Inf
+	andb	$0x45, %ch
+	cmpb	$5, %ch
+	jne	4f		// jump if x is not Inf
+	fxch
+3:	fstp	%st(1)
+	fabs
+	jmp	2b
+
+4:	testb	$1, %al
+	jnz	5f		// y is NaN
+	fxch
+5:	fstp	%st(1)
+	jmp	2b
+	
+END(__ieee754_hypot)
diff --git a/sysdeps/i386/fpu/e_hypotf.S b/sysdeps/i386/fpu/e_hypotf.S
new file mode 100644
index 0000000000..bf5416b664
--- /dev/null
+++ b/sysdeps/i386/fpu/e_hypotf.S
@@ -0,0 +1,62 @@
+/* Compute the hypothenuse of X and Y.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   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>
+
+	.text
+ENTRY(__ieee754_hypotf)
+	flds	4(%esp)		// x
+	fxam
+	fnstsw
+	flds	8(%esp)		// y : x
+	movb	%ah, %ch
+	fxam
+	fnstsw
+	movb	%ah, %al
+	orb	%ch, %ah
+	sahf
+	jc	1f
+	fmul	%st(0)		// y * y : x
+	fxch			// x : y * y
+	fmul	%st(0)		// x * x : y * y
+	faddp			// x * x + y * y
+	fsqrt
+2:	ret
+
+	// We have to test whether any of the parameters is Inf.
+	// In this case the result is infinity.
+1:	andb	$0x45, %al
+	cmpb	$5, %al
+	je	3f		// jump if y is Inf
+	andb	$0x45, %ch
+	cmpb	$5, %ch
+	jne	4f		// jump if x is not Inf
+	fxch
+3:	fstp	%st(1)
+	fabs
+	jmp	2b
+
+4:	testb	$1, %al
+	jnz	5f		// y is NaN
+	fxch
+5:	fstp	%st(1)
+	jmp	2b
+	
+END(__ieee754_hypotf)
diff --git a/sysdeps/i386/fpu/e_log.S b/sysdeps/i386/fpu/e_log.S
new file mode 100644
index 0000000000..c7cacdfb0a
--- /dev/null
+++ b/sysdeps/i386/fpu/e_log.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_log.S,v 1.4 1995/05/08 23:48:39 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_log)
+	fldln2			// log(2)
+	fldl	4(%esp)		// x : log(2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fld	%st		// x : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
+	fld	%st		// x-1 : x-1 : x : log(2)
+	fabs			// |x-1| : x-1 : x : log(2)
+	fcompl	MO(limit)	// x-1 : x : log(2)
+	fnstsw			// x-1 : x : log(2)
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : log(2)
+	fyl2xp1			// log(x)
+	ret
+
+2:	fstp	%st(0)		// x : log(2)
+	fyl2x			// log(x)
+	ret
+END (__ieee754_log)
diff --git a/sysdeps/i386/fpu/e_log10.S b/sysdeps/i386/fpu/e_log10.S
new file mode 100644
index 0000000000..2c8488c3a9
--- /dev/null
+++ b/sysdeps/i386/fpu/e_log10.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_log10.S,v 1.4 1995/05/08 23:49:24 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_log10)
+	fldlg2			// log10(2)
+	fldl	4(%esp)		// x : log10(2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fld	%st		// x : x : log10(2)
+	fsubl	MO(one)		// x-1 : x : log10(2)
+	fld	%st		// x-1 : x-1 : x : log10(2)
+	fabs			// |x-1| : x-1 : x : log10(2)
+	fcompl	MO(limit)	// x-1 : x : log10(2)
+	fnstsw			// x-1 : x : log10(2)
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : log10(2)
+	fyl2xp1			// log10(x)
+	ret
+
+2:	fstp	%st(0)		// x : log10(2)
+	fyl2x			// log10(x)
+	ret
+END (__ieee754_log10)
diff --git a/sysdeps/i386/fpu/e_log10f.S b/sysdeps/i386/fpu/e_log10f.S
new file mode 100644
index 0000000000..2c07161085
--- /dev/null
+++ b/sysdeps/i386/fpu/e_log10f.S
@@ -0,0 +1,60 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_log10f)
+	fldlg2			// log10(2)
+	flds	4(%esp)		// x : log10(2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fld	%st		// x : x : log10(2)
+	fsubl	MO(one)		// x-1 : x : log10(2)
+	fld	%st		// x-1 : x-1 : x : log10(2)
+	fabs			// |x-1| : x-1 : x : log10(2)
+	fcompl	MO(limit)	// x-1 : x : log10(2)
+	fnstsw			// x-1 : x : log10(2)
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : log10(2)
+	fyl2xp1			// log10(x)
+	ret
+
+2:	fstp	%st(0)		// x : log10(2)
+	fyl2x			// log10(x)
+	ret
+END (__ieee754_log10f)
diff --git a/sysdeps/i386/fpu/e_log10l.S b/sysdeps/i386/fpu/e_log10l.S
new file mode 100644
index 0000000000..6fe7c5a6f7
--- /dev/null
+++ b/sysdeps/i386/fpu/e_log10l.S
@@ -0,0 +1,61 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_log10l)
+	fldlg2			// log10(2)
+	fldt	4(%esp)		// x : log10(2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fld	%st		// x : x : log10(2)
+	fsubl	MO(one)		// x-1 : x : log10(2)
+	fld	%st		// x-1 : x-1 : x : log10(2)
+	fabs			// |x-1| : x-1 : x : log10(2)
+	fcompl	MO(limit)	// x-1 : x : log10(2)
+	fnstsw			// x-1 : x : log10(2)
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : log10(2)
+	fyl2xp1			// log10(x)
+	ret
+
+2:	fstp	%st(0)		// x : log10(2)
+	fyl2x			// log10(x)
+	ret
+END(__ieee754_log10l)
diff --git a/sysdeps/i386/fpu/e_logf.S b/sysdeps/i386/fpu/e_logf.S
new file mode 100644
index 0000000000..bdba1d3225
--- /dev/null
+++ b/sysdeps/i386/fpu/e_logf.S
@@ -0,0 +1,60 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_log.S,v 1.4 1995/05/08 23:48:39 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_logf)
+	fldln2			// log(2)
+	flds	4(%esp)		// x : log(2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fld	%st		// x : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
+	fld	%st		// x-1 : x-1 : x : log(2)
+	fabs			// |x-1| : x-1 : x : log(2)
+	fcompl	MO(limit)	// x-1 : x : log(2)
+	fnstsw			// x-1 : x : log(2)
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : log(2)
+	fyl2xp1			// log(x)
+	ret
+
+2:	fstp	%st(0)		// x : log(2)
+	fyl2x			// log(x)
+	ret
+END (__ieee754_logf)
diff --git a/sysdeps/i386/fpu/e_logl.S b/sysdeps/i386/fpu/e_logl.S
new file mode 100644
index 0000000000..bda3ea508e
--- /dev/null
+++ b/sysdeps/i386/fpu/e_logl.S
@@ -0,0 +1,60 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__ieee754_logl)
+	fldln2			// log(2)
+	fldt	4(%esp)		// x : log(2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fld	%st		// x : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
+	fld	%st		// x-1 : x-1 : x : log(2)
+	fabs			// |x-1| : x-1 : x : log(2)
+	fcompl	MO(limit)	// x-1 : x : log(2)
+	fnstsw			// x-1 : x : log(2)
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : log(2)
+	fyl2xp1			// log(x)
+	ret
+
+2:	fstp	%st(0)		// x : log(2)
+	fyl2x			// log(x)
+	ret
+END (__ieee754_logl)
diff --git a/sysdeps/i386/fpu/e_pow.S b/sysdeps/i386/fpu/e_pow.S
new file mode 100644
index 0000000000..75ad211872
--- /dev/null
+++ b/sysdeps/i386/fpu/e_pow.S
@@ -0,0 +1,320 @@
+/* ix87 specific implementation of pow function.
+   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#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)
+
+#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	12(%esp)	// y
+	fxam
+
+#ifdef	PIC
+	call	1f
+1:	popl	%ecx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+
+	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
+
+	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
+	fistpll	(%esp)		// y : x
+	fildll	(%esp)		// int(y) : y : x
+	fucomp	%st(1)		// y : x
+	fnstsw
+	sahf
+	jne	2f
+
+	/* OK, we have an integer value for y.  */
+	popl	%eax
+	popl	%edx
+	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
+	jnc	5f
+	fxch
+	fmul	%st(1)		// x : ST*x
+	fxch
+5:	fmul	%st(0), %st	// x*x : ST*x
+	shrl	$1, %edx
+	movl	%eax, %ecx
+	orl	%edx, %ecx
+	jnz	6b
+	fstp	%st(0)		// ST*x
+30:	ret
+
+	.align ALIGNARG(4)
+2:	/* y is a real number.  */
+	fxch			// x : y
+	fldl	MO(one)		// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
+	fnstsw
+	fxch			// x : 1.0 : y
+	sahf
+	ja	7f
+	fsub	%st(1)		// x-1 : 1.0 : y
+	fyl2xp1			// log2(x) : y
+	jmp	8f
+
+7:	fyl2x			// log2(x) : y
+8:	fmul	%st(1)		// y*log2(x) : y
+	fst	%st(1)		// y*log2(x) : y*log2(x)
+	frndint			// int(y*log2(x)) : y*log2(x)
+	fsubr	%st, %st(1)	// int(y*log2(x)) : fract(y*log2(x))
+	fxch			// fract(y*log2(x)) : int(y*log2(x))
+	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
+	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(infinity)
+	fmull	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
+	jae	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/i386/fpu/e_powf.S b/sysdeps/i386/fpu/e_powf.S
new file mode 100644
index 0000000000..d7342bf56f
--- /dev/null
+++ b/sysdeps/i386/fpu/e_powf.S
@@ -0,0 +1,310 @@
+/* ix87 specific implementation of pow function.
+   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.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#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)
+
+#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	8(%esp)	// y
+	fxam
+
+#ifdef	PIC
+	call	1f
+1:	popl	%ecx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+
+	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
+
+	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
+	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.  */
+	popl	%edx
+	orl	$0, %edx
+	fstp	%st(0)		// x
+	jns	4f		// y >= 0, jump
+	fdivrl	MO(one)		// 1/x		(now referred to as x)
+	negl	%edx
+4:	fldl	MO(one)		// 1 : x
+	fxch
+
+6:	shrl	$1, %edx
+	jnc	5f
+	fxch
+	fmul	%st(1)		// x : ST*x
+	fxch
+5:	fmul	%st(0), %st	// x*x : ST*x
+	testl	%edx, %edx
+	jnz	6b
+	fstp	%st(0)		// ST*x
+30:	ret
+
+	.align ALIGNARG(4)
+2:	/* y is a real number.  */
+	fxch			// x : y
+	fldl	MO(one)		// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
+	fnstsw
+	fxch			// x : 1.0 : y
+	sahf
+	ja	7f
+	fsub	%st(1)		// x-1 : 1.0 : y
+	fyl2xp1			// log2(x) : y
+	jmp	8f
+
+7:	fyl2x			// log2(x) : y
+8:	fmul	%st(1)		// y*log2(x) : y
+	fst	%st(1)		// y*log2(x) : y*log2(x)
+	frndint			// int(y*log2(x)) : y*log2(x)
+	fsubr	%st, %st(1)	// int(y*log2(x)) : fract(y*log2(x))
+	fxch			// fract(y*log2(x)) : int(y*log2(x))
+	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	$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(infinity)
+	fmull	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
+	jae	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/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S
new file mode 100644
index 0000000000..2e09dcc820
--- /dev/null
+++ b/sysdeps/i386/fpu/e_powl.S
@@ -0,0 +1,307 @@
+/* ix87 specific implementation of pow function.
+   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#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)
+
+#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	16(%esp)	// y
+	fxam
+
+#ifdef	PIC
+	call	1f
+1:	popl	%ecx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+
+	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
+
+	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
+	fistpll	(%esp)		// y : x
+	fildll	(%esp)		// int(y) : y : x
+	fucomp	%st(1)		// y : x
+	fnstsw
+	sahf
+	jne	2f
+
+	/* OK, we have an integer value for y.  */
+	popl	%eax
+	popl	%edx
+	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
+	jnc	5f
+	fxch
+	fmul	%st(1)		// x : ST*x
+	fxch
+5:	fmul	%st(0), %st	// x*x : ST*x
+	shrl	$1, %edx
+	movl	%eax, %ecx
+	orl	%edx, %ecx
+	jnz	6b
+	fstp	%st(0)		// ST*x
+30:	ret
+
+	.align ALIGNARG(4)
+2:	/* y is a real number.  */
+	fxch			// x : y
+	fldl	MO(one)		// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
+	fnstsw
+	fxch			// x : 1.0 : y
+	sahf
+	ja	7f
+	fsub	%st(1)		// x-1 : 1.0 : y
+	fyl2xp1			// log2(x) : y
+	jmp	8f
+
+7:	fyl2x			// log2(x) : y
+8:	fmul	%st(1)		// y*log2(x) : y
+	fst	%st(1)		// y*log2(x) : y*log2(x)
+	frndint			// int(y*log2(x)) : y*log2(x)
+	fsubr	%st, %st(1)	// int(y*log2(x)) : fract(y*log2(x))
+	fxch			// fract(y*log2(x)) : int(y*log2(x))
+	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
+	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(infinity)
+	fmull	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/i386/fpu/e_rem_pio2.c b/sysdeps/i386/fpu/e_rem_pio2.c
new file mode 100644
index 0000000000..1347b0468c
--- /dev/null
+++ b/sysdeps/i386/fpu/e_rem_pio2.c
@@ -0,0 +1,3 @@
+/* Empty.  This file is only meant to avoid compiling the file with the
+   same name in the libm-ieee754 directory.  The code is not used since
+   there is an assembler version for all users of this file.  */
diff --git a/sysdeps/i386/fpu/e_rem_pio2f.c b/sysdeps/i386/fpu/e_rem_pio2f.c
new file mode 100644
index 0000000000..1347b0468c
--- /dev/null
+++ b/sysdeps/i386/fpu/e_rem_pio2f.c
@@ -0,0 +1,3 @@
+/* Empty.  This file is only meant to avoid compiling the file with the
+   same name in the libm-ieee754 directory.  The code is not used since
+   there is an assembler version for all users of this file.  */
diff --git a/sysdeps/i386/fpu/e_rem_pio2l.c b/sysdeps/i386/fpu/e_rem_pio2l.c
new file mode 100644
index 0000000000..1347b0468c
--- /dev/null
+++ b/sysdeps/i386/fpu/e_rem_pio2l.c
@@ -0,0 +1,3 @@
+/* Empty.  This file is only meant to avoid compiling the file with the
+   same name in the libm-ieee754 directory.  The code is not used since
+   there is an assembler version for all users of this file.  */
diff --git a/sysdeps/i386/fpu/e_remainder.S b/sysdeps/i386/fpu/e_remainder.S
new file mode 100644
index 0000000000..2f43cb894c
--- /dev/null
+++ b/sysdeps/i386/fpu/e_remainder.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_remainder.S,v 1.4 1995/05/08 23:49:37 jtc Exp $")
+
+ENTRY(__ieee754_remainder)
+	fldl	12(%esp)
+	fldl	4(%esp)
+1:	fprem1
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	ret
+END (__ieee754_remainder)
diff --git a/sysdeps/i386/fpu/e_remainderf.S b/sysdeps/i386/fpu/e_remainderf.S
new file mode 100644
index 0000000000..79f821993b
--- /dev/null
+++ b/sysdeps/i386/fpu/e_remainderf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_remainderf.S,v 1.2 1995/05/08 23:49:47 jtc Exp $")
+
+ENTRY(__ieee754_remainderf)
+	flds	8(%esp)
+	flds	4(%esp)
+1:	fprem1
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	ret
+END (__ieee754_remainderf)
diff --git a/sysdeps/i386/fpu/e_remainderl.S b/sysdeps/i386/fpu/e_remainderl.S
new file mode 100644
index 0000000000..5f50b626a2
--- /dev/null
+++ b/sysdeps/i386/fpu/e_remainderl.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_remainderl)
+	fldt	16(%esp)
+	fldt	4(%esp)
+1:	fprem1
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	ret
+END (__ieee754_remainderl)
diff --git a/sysdeps/i386/fpu/e_scalb.S b/sysdeps/i386/fpu/e_scalb.S
new file mode 100644
index 0000000000..7ff5541e2f
--- /dev/null
+++ b/sysdeps/i386/fpu/e_scalb.S
@@ -0,0 +1,94 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_scalb.S,v 1.4 1995/05/08 23:49:52 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+	.double 0.0
+nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	ASM_SIZE_DIRECTIVE(zero_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_scalb)
+	fldl	12(%esp)
+	fxam
+	fnstsw
+	fldl	4(%esp)
+	andl	$0x4700, %eax
+	cmpl	$0x0700, %eax
+	je	1f
+	andl	$0x4500, %eax
+	cmpl	$0x0100, %eax
+	je	2f
+	fxam
+	fnstsw
+	andl	$0x4500, %eax
+	cmpl	$0x0100, %eax
+	je	2f
+	fld	%st(1)
+	frndint
+	fcomp	%st(2)
+	fnstsw
+	sahf
+	jne	2f
+	fscale
+	fstp	%st(1)
+	ret
+
+	/* y is -inf */
+1:	fxam
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	fnstsw
+	movl	8(%esp), %edx
+	shrl	$5, %eax
+	fstp	%st
+	fstp	%st
+	andl	$0x80000000, %edx
+	andl	$8, %eax
+	shrl	$27, %edx
+	addl	%edx, %eax
+	fldl	MOX(zero_nan, %eax, 1)
+	ret
+
+	/* The result is NaN, but we must not raise an exception.
+	   So use a variable.  */
+2:	fstp	%st
+	fstp	%st
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	fldl	MO(nan)
+	ret
+END(__ieee754_scalb)
diff --git a/sysdeps/i386/fpu/e_scalbf.S b/sysdeps/i386/fpu/e_scalbf.S
new file mode 100644
index 0000000000..4222eecc97
--- /dev/null
+++ b/sysdeps/i386/fpu/e_scalbf.S
@@ -0,0 +1,96 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+	.double 0.0
+nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	ASM_SIZE_DIRECTIVE(zero_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_scalbf)
+	flds	8(%esp)
+	fxam
+	fnstsw
+	flds	4(%esp)
+	andl	$0x4700, %eax
+	cmpl	$0x0700, %eax
+	je	1f
+	andl	$0x4500, %eax
+	cmpl	$0x0100, %eax
+	je	2f
+	fxam
+	fnstsw
+	andl	$0x4500, %eax
+	cmpl	$0x0100, %eax
+	je	2f
+	fld	%st(1)
+	frndint
+	fcomp	%st(2)
+	fnstsw
+	sahf
+	jne	2f
+	fscale
+	fstp	%st(1)
+	ret
+
+	/* y is -inf */
+1:	fxam
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	fnstsw
+	movl	4(%esp), %edx
+	shrl	$5, %eax
+	fstp	%st
+	fstp	%st
+	andl	$0x80000000, %edx
+	andl	$8, %eax
+	shrl	$27, %edx
+	addl	%edx, %eax
+	fldl	MOX(zero_nan, %eax, 1)
+	ret
+
+	/* The result is NaN, but we must not raise an exception.
+	   So use a variable.  */
+2:	fstp	%st
+	fstp	%st
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	fldl	MO(nan)
+	ret
+END(__ieee754_scalbf)
diff --git a/sysdeps/i386/fpu/e_scalbl.S b/sysdeps/i386/fpu/e_scalbl.S
new file mode 100644
index 0000000000..56cc833a56
--- /dev/null
+++ b/sysdeps/i386/fpu/e_scalbl.S
@@ -0,0 +1,96 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+	.double 0.0
+nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
+	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+	ASM_SIZE_DIRECTIVE(zero_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_scalbl)
+	fldt	16(%esp)
+	fxam
+	fnstsw
+	fldt	4(%esp)
+	andl	$0x4700, %eax
+	cmpl	$0x0700, %eax
+	je	1f
+	andl	$0x4500, %eax
+	cmpl	$0x0100, %eax
+	je	2f
+	fxam
+	fnstsw
+	andl	$0x4500, %eax
+	cmpl	$0x0100, %eax
+	je	2f
+	fld	%st(1)
+	frndint
+	fcomp	%st(2)
+	fnstsw
+	sahf
+	jne	2f
+	fscale
+	fstp	%st(1)
+	ret
+
+	/* y is -inf */
+1:	fxam
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	fnstsw
+	movl	12(%esp), %edx
+	shrl	$5, %eax
+	fstp	%st
+	fstp	%st
+	andl	$0x8000, %edx
+	andl	$8, %eax
+	shrl	$11, %edx
+	addl	%edx, %eax
+	fldl	MOX(zero_nan, %eax, 1)
+	ret
+
+	/* The result is NaN, but we must not raise an exception.
+	   So use a variable.  */
+2:	fstp	%st
+	fstp	%st
+#ifdef  PIC
+        call    1f
+1:      popl    %ecx
+        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+#endif
+	fldl	MO(nan)
+	ret
+END(__ieee754_scalbl)
diff --git a/sysdeps/i386/fpu/e_sqrt.S b/sysdeps/i386/fpu/e_sqrt.S
new file mode 100644
index 0000000000..6f253d51aa
--- /dev/null
+++ b/sysdeps/i386/fpu/e_sqrt.S
@@ -0,0 +1,14 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrt.S,v 1.4 1995/05/08 23:49:57 jtc Exp $")
+
+ENTRY(__ieee754_sqrt)
+	fldl	4(%esp)
+	fsqrt
+	ret
+END (__ieee754_sqrt)
diff --git a/sysdeps/i386/fpu/e_sqrtf.S b/sysdeps/i386/fpu/e_sqrtf.S
new file mode 100644
index 0000000000..5ce1ad0544
--- /dev/null
+++ b/sysdeps/i386/fpu/e_sqrtf.S
@@ -0,0 +1,14 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrtf.S,v 1.2 1995/05/08 23:50:14 jtc Exp $")
+
+ENTRY(__ieee754_sqrtf)
+	flds	4(%esp)
+	fsqrt
+	ret
+END (__ieee754_sqrtf)
diff --git a/sysdeps/i386/fpu/e_sqrtl.S b/sysdeps/i386/fpu/e_sqrtl.S
new file mode 100644
index 0000000000..d47aae5cb5
--- /dev/null
+++ b/sysdeps/i386/fpu/e_sqrtl.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_sqrtl)
+	fldt	4(%esp)
+	fsqrt
+	ret
+END (__ieee754_sqrtl)
diff --git a/sysdeps/i386/fpu/k_rem_pio2.c b/sysdeps/i386/fpu/k_rem_pio2.c
new file mode 100644
index 0000000000..1347b0468c
--- /dev/null
+++ b/sysdeps/i386/fpu/k_rem_pio2.c
@@ -0,0 +1,3 @@
+/* Empty.  This file is only meant to avoid compiling the file with the
+   same name in the libm-ieee754 directory.  The code is not used since
+   there is an assembler version for all users of this file.  */
diff --git a/sysdeps/i386/fpu/k_rem_pio2f.c b/sysdeps/i386/fpu/k_rem_pio2f.c
new file mode 100644
index 0000000000..1347b0468c
--- /dev/null
+++ b/sysdeps/i386/fpu/k_rem_pio2f.c
@@ -0,0 +1,3 @@
+/* Empty.  This file is only meant to avoid compiling the file with the
+   same name in the libm-ieee754 directory.  The code is not used since
+   there is an assembler version for all users of this file.  */
diff --git a/sysdeps/i386/fpu/k_rem_pio2l.c b/sysdeps/i386/fpu/k_rem_pio2l.c
new file mode 100644
index 0000000000..1347b0468c
--- /dev/null
+++ b/sysdeps/i386/fpu/k_rem_pio2l.c
@@ -0,0 +1,3 @@
+/* Empty.  This file is only meant to avoid compiling the file with the
+   same name in the libm-ieee754 directory.  The code is not used since
+   there is an assembler version for all users of this file.  */
diff --git a/sysdeps/i386/fpu/s_asinh.S b/sysdeps/i386/fpu/s_asinh.S
new file mode 100644
index 0000000000..a4c52cb67c
--- /dev/null
+++ b/sysdeps/i386/fpu/s_asinh.S
@@ -0,0 +1,139 @@
+/* ix87 specific implementation of arcsinh.
+   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.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(huge,@object)
+huge:	.double 1e+300
+	ASM_SIZE_DIRECTIVE(huge)
+	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)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__asinh)
+	movl	8(%esp), %ecx
+	movl	$0x7fffffff, %eax
+	andl	%ecx, %eax
+	andl	$0x80000000, %ecx
+	movl	%eax, %edx
+	orl	$0x800fffff, %edx
+	incl	%edx
+	jz	7f			// x in ±Inf or NaN
+	xorl	%ecx, 8(%esp)
+	fldl	4(%esp)			// |x|
+	cmpl	$0x3e300000, %eax
+	jb	2f			// |x| < 2^-28
+	fldln2				// log(2) : |x|
+	cmpl	$0x41b00000, %eax
+	fxch				// |x| : log(2)
+	ja	3f			// |x| > 2^28
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpl	$0x40000000, %eax
+	ja	5f			// |x| > 2
+
+	// 2^-28 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
+	fld	%st			// |x| : |x| : log(2)
+	fmul	%st(1)			// |x|^2 : |x| : log(2)
+	fld	%st			// |x|^2 : |x|^2 : |x| : log(2)
+	faddl	MO(one)			// 1+|x|^2 : |x|^2 : |x| : log(2)
+	fsqrt				// sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+	faddl	MO(one)			// 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+	fdivrp				// |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
+	faddp				// |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
+	fcoml	MO(limit)
+	fnstsw
+	sahf
+	ja	6f
+	fyl2xp1
+	jecxz	4f
+	fchs
+4:	ret
+
+7:	fldl	4(%esp)
+	ret
+
+6:	faddl	MO(one)
+	fyl2x
+	jecxz	4f
+	fchs
+4:	ret
+
+	// |x| < 2^-28 => y = x (inexact iff |x| != 0.0)
+	.align ALIGNARG(4)
+2:
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	jecxz	4f
+	fchs				// x
+4:	fld	%st			// x : x
+	faddl	MO(huge)		// huge+x : x
+	fstp	%st(0)			// x
+	ret
+
+	// |x| > 2^28 => y = sign(x) * (log(|x|) + log(2))
+	.align ALIGNARG(4)
+3:	fyl2x				// log(|x|)
+	fldln2				// log(2) : log(|x|)
+	faddp				// log(|x|)+log(2)
+	jecxz	4f
+	fchs
+4:	ret
+
+	// |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
+	.align ALIGNARG(4)
+5:	fld	%st			// |x| : |x| : log(2)
+	fadd	%st, %st(1)		// |x| : 2*|x| : log(2)
+	fld	%st			// |x| : |x| : 2*|x| : log(2)
+	fmul	%st(1)			// |x|^2 : |x| : 2*|x| : log(2)
+	faddl	MO(one)			// 1+|x|^2 : |x| : 2*|x| : log(2)
+	fsqrt				// sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
+	faddp				// |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
+	fdivrl	MO(one)			// 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
+	faddp				// 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
+	fyl2x				// log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
+	jecxz	4f
+	fchs
+4:	ret
+END(__asinh)
+weak_alias (__asinh, asinh)
diff --git a/sysdeps/i386/fpu/s_asinhf.S b/sysdeps/i386/fpu/s_asinhf.S
new file mode 100644
index 0000000000..a6925c7b4c
--- /dev/null
+++ b/sysdeps/i386/fpu/s_asinhf.S
@@ -0,0 +1,139 @@
+/* ix87 specific implementation of arcsinh.
+   Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(huge,@object)
+huge:	.double 1e+36
+	ASM_SIZE_DIRECTIVE(huge)
+	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)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__asinhf)
+	movl	4(%esp), %ecx
+	movl	$0x7fffffff, %eax
+	andl	%ecx, %eax
+	andl	$0x80000000, %ecx
+	movl	%eax, %edx
+	orl	$0x807fffff, %edx
+	incl	%edx
+	jz	7f			// x in ±Inf or NaN
+	xorl	%ecx, 4(%esp)
+	flds	4(%esp)			// |x|
+	cmpl	$0x38000000, %eax
+	jb	2f			// |x| < 2^-14
+	fldln2				// log(2) : |x|
+	cmpl	$0x47000000, %eax
+	fxch				// |x| : log(2)
+	ja	3f			// |x| > 2^14
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpl	$0x40000000, %eax
+	ja	5f			// |x| > 2
+
+	// 2^-14 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
+	fld	%st			// |x| : |x| : log(2)
+	fmul	%st(1)			// |x|^2 : |x| : log(2)
+	fld	%st			// |x|^2 : |x|^2 : |x| : log(2)
+	faddl	MO(one)			// 1+|x|^2 : |x|^2 : |x| : log(2)
+	fsqrt				// sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+	faddl	MO(one)			// 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+	fdivrp				// |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
+	faddp				// |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
+	fcoml	MO(limit)
+	fnstsw
+	sahf
+	ja	6f
+	fyl2xp1
+	jecxz	4f
+	fchs
+4:	ret
+
+7:	flds	4(%esp)
+	ret
+
+6:	faddl	MO(one)
+	fyl2x
+	jecxz	4f
+	fchs
+4:	ret
+
+	// |x| < 2^-14 => y = x (inexact iff |x| != 0.0)
+	.align ALIGNARG(4)
+2:
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	jecxz	4f
+	fchs				// x
+4:	fld	%st			// x : x
+	faddl	MO(huge)		// huge+x : x
+	fstp	%st(0)			// x
+	ret
+
+	// |x| > 2^14 => y = sign(x) * (log(|x|) + log(2))
+	.align ALIGNARG(4)
+3:	fyl2x				// log(|x|)
+	fldln2				// log(2) : log(|x|)
+	faddp				// log(|x|)+log(2)
+	jecxz	4f
+	fchs
+4:	ret
+
+	// |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
+	.align ALIGNARG(4)
+5:	fld	%st			// |x| : |x| : log(2)
+	fadd	%st, %st(1)		// |x| : 2*|x| : log(2)
+	fld	%st			// |x| : |x| : 2*|x| : log(2)
+	fmul	%st(1)			// |x|^2 : |x| : 2*|x| : log(2)
+	faddl	MO(one)			// 1+|x|^2 : |x| : 2*|x| : log(2)
+	fsqrt				// sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
+	faddp				// |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
+	fdivrl	MO(one)			// 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
+	faddp				// 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
+	fyl2x				// log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
+	jecxz	4f
+	fchs
+4:	ret
+END(__asinhf)
+weak_alias (__asinhf, asinhf)
diff --git a/sysdeps/i386/fpu/s_asinhl.S b/sysdeps/i386/fpu/s_asinhl.S
new file mode 100644
index 0000000000..62e29bc58e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_asinhl.S
@@ -0,0 +1,147 @@
+/* ix87 specific implementation of arcsinh.
+   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.
+
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(huge,@object)
+huge:	.tfloat 1e+4930
+	ASM_SIZE_DIRECTIVE(huge)
+	.align ALIGNARG(4)
+	/* Please note that we use double value for 1.0.  This number
+	   has an exact representation and so we don't get accuracy
+	   problems.  The advantage is that the code is simpler.  */
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__asinhl)
+	movl	12(%esp), %ecx
+	movl	$0x7fff, %eax
+	andl	%ecx, %eax
+	andl	$0x8000, %ecx
+	movl	%eax, %edx
+	orl	$0xffff8000, %edx
+	incl	%edx
+	jz	7f			// x in ±Inf or NaN
+	xorl	%ecx, 12(%esp)
+	fldt	4(%esp)			// |x|
+	cmpl	$0x3fde, %eax
+	jb	2f			// |x| < 2^-34
+	fldln2				// log(2) : |x|
+	cmpl	$0x4020, %eax
+	fxch				// |x| : log(2)
+	ja	3f			// |x| > 2^34
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpl	$0x4000, %eax
+	ja	5f			// |x| > 2
+
+	// 2^-34 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
+	fld	%st			// |x| : |x| : log(2)
+	fmul	%st(1)			// |x|^2 : |x| : log(2)
+	fld	%st			// |x|^2 : |x|^2 : |x| : log(2)
+	faddl	MO(one)			// 1+|x|^2 : |x|^2 : |x| : log(2)
+	fsqrt				// sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+	faddl	MO(one)			// 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+	fdivrp				// |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
+	faddp				// |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
+	fcoml	MO(limit)
+	fnstsw
+	sahf
+	ja	6f
+	fyl2xp1
+	jecxz	4f
+	fchs
+4:	ret
+
+7:	fldt	4(%esp)
+	ret
+
+6:	faddl	MO(one)
+	fyl2x
+	jecxz	4f
+	fchs
+4:	ret
+
+	// |x| < 2^-34 => y = x (inexact iff |x| != 0.0)
+	.align ALIGNARG(4)
+2:
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	jecxz	4f
+	fchs				// x
+4:	fld	%st			// x : x
+	fldt	MO(huge)		// huge : x : x
+	faddp				// huge+x : x
+	fstp	%st(0)			// x
+	ret
+
+	// |x| > 2^34 => y = sign(x) * (log(|x|) + log(2))
+	.align ALIGNARG(4)
+3:	fyl2x				// log(|x|)
+	fldln2				// log(2) : log(|x|)
+	faddp				// log(|x|)+log(2)
+	jecxz	4f
+	fchs
+4:	ret
+
+	// |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
+	.align ALIGNARG(4)
+5:	fld	%st			// |x| : |x| : log(2)
+	fadd	%st, %st(1)		// |x| : 2*|x| : log(2)
+	fld	%st			// |x| : |x| : 2*|x| : log(2)
+	fmul	%st(1)			// |x|^2 : |x| : 2*|x| : log(2)
+	faddl	MO(one)			// 1+|x|^2 : |x| : 2*|x| : log(2)
+	fsqrt				// sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
+	faddp				// |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
+	fdivrl	MO(one)			// 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
+	faddp				// 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
+	fyl2x				// log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
+	jecxz	4f
+	fchs
+4:	ret
+END(__asinhl)
+weak_alias (__asinhl, asinhl)
diff --git a/sysdeps/i386/fpu/s_atan.S b/sysdeps/i386/fpu/s_atan.S
new file mode 100644
index 0000000000..7502f6d828
--- /dev/null
+++ b/sysdeps/i386/fpu/s_atan.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_atan.S,v 1.4 1995/05/08 23:50:41 jtc Exp $")
+
+ENTRY(__atan)
+	fldl	4(%esp)
+	fld1
+	fpatan
+	ret
+END (__atan)
+weak_alias (__atan, atan)
diff --git a/sysdeps/i386/fpu/s_atanf.S b/sysdeps/i386/fpu/s_atanf.S
new file mode 100644
index 0000000000..70232c8240
--- /dev/null
+++ b/sysdeps/i386/fpu/s_atanf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_atanf.S,v 1.3 1995/05/08 23:51:33 jtc Exp $")
+
+ENTRY(__atanf)
+	flds	4(%esp)
+	fld1
+	fpatan
+	ret
+END (__atanf)
+weak_alias (__atanf, atanf)
diff --git a/sysdeps/i386/fpu/s_atanl.S b/sysdeps/i386/fpu/s_atanl.S
new file mode 100644
index 0000000000..8b07272764
--- /dev/null
+++ b/sysdeps/i386/fpu/s_atanl.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__atanl)
+	fldt	4(%esp)
+	fld1
+	fpatan
+	ret
+END (__atanl)
+weak_alias (__atanl, atanl)
diff --git a/sysdeps/i386/fpu/s_cbrt.S b/sysdeps/i386/fpu/s_cbrt.S
new file mode 100644
index 0000000000..3f6a0174f2
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cbrt.S
@@ -0,0 +1,201 @@
+/* Compute cubic root of double value.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+        .section .rodata
+#else
+        .text
+#endif
+
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f7,@object)
+f7:	.double -0.145263899385486377
+	ASM_SIZE_DIRECTIVE(f7)
+        ASM_TYPE_DIRECTIVE(f6,@object)
+f6:	.double 0.784932344976639262
+	ASM_SIZE_DIRECTIVE(f6)
+        ASM_TYPE_DIRECTIVE(f5,@object)
+f5:	.double -1.83469277483613086
+	ASM_SIZE_DIRECTIVE(f5)
+        ASM_TYPE_DIRECTIVE(f4,@object)
+f4:	.double 2.44693122563534430
+	ASM_SIZE_DIRECTIVE(f4)
+        ASM_TYPE_DIRECTIVE(f3,@object)
+f3:	.double -2.11499494167371287
+	ASM_SIZE_DIRECTIVE(f3)
+        ASM_TYPE_DIRECTIVE(f2,@object)
+f2:	.double 1.50819193781584896
+	ASM_SIZE_DIRECTIVE(f2)
+        ASM_TYPE_DIRECTIVE(f1,@object)
+f1:	.double 0.354895765043919860
+	ASM_SIZE_DIRECTIVE(f1)
+
+#define CBRT2		1.2599210498948731648
+#define ONE_CBRT2	0.793700525984099737355196796584
+#define SQR_CBRT2	1.5874010519681994748
+#define ONE_SQR_CBRT2	0.629960524947436582364439673883
+
+	ASM_TYPE_DIRECTIVE(factor,@object)
+factor:	.double ONE_SQR_CBRT2
+	.double ONE_CBRT2
+	.double 1.0
+	.double CBRT2
+	.double SQR_CBRT2
+	ASM_SIZE_DIRECTIVE(factor)
+
+        ASM_TYPE_DIRECTIVE(two54,@object)
+two54:  .byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
+        ASM_SIZE_DIRECTIVE(two54)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ebx)
+#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
+#else
+#define MO(op) op
+#define MOX(op,x) op(x)
+#endif
+
+	.text
+ENTRY(__cbrt)
+	movl	4(%esp), %ecx
+	movl	8(%esp), %eax
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+	orl	%eax, %ecx
+	jz	1f
+	xorl	%ecx, %ecx
+	cmpl	$0x7ff00000, %eax
+	jae	1f
+
+#ifdef PIC
+	pushl	%ebx
+	call	3f
+3:	popl	%ebx
+	addl    $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
+#endif
+
+	cmpl	$0x00100000, %eax
+	jae	2f
+
+#ifdef PIC
+	fldl	8(%esp)
+#else
+	fldl	4(%esp)
+#endif
+	fmull	MO(two54)
+	movl	$-54, %ecx
+#ifdef PIC
+	fstpl	8(%esp)
+	movl	12(%esp), %eax
+#else
+	fstpl	4(%esp)
+	movl	8(%esp), %eax
+#endif
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+
+2:	shrl	$20, %eax
+	andl	$0x800fffff, %edx
+	subl	$1022, %eax
+	orl	$0x3fe00000, %edx
+	addl	%eax, %ecx
+#ifdef PIC
+	movl	%edx, 12(%esp)
+
+	fldl	8(%esp)			/* xm */
+#else
+	movl	%edx, 8(%esp)
+
+	fldl	4(%esp)			/* xm */
+#endif
+	fabs
+
+	/* The following code has two tracks:
+	    a) compute the normalized cbrt value
+	    b) compute xe/3 and xe%3
+	   The right track computes the value for b) and this is done
+	   in an optimized way by avoiding division.
+
+	   But why two tracks at all?  Very easy: efficiency.  Some FP
+	   instruction can overlap with a certain amount of integer (and
+	   FP) instructions.  So we get (except for the imull) all
+	   instructions for free.  */
+
+	fld	%st(0)			/* xm : xm */
+
+	fmull	MO(f7)			/* f7*xm : xm */
+			movl	$1431655766, %eax
+	faddl	MO(f6)			/* f6+f7*xm : xm */
+			imull	%ecx
+	fmul	%st(1)			/* (f6+f7*xm)*xm : xm */
+			movl	%ecx, %eax
+	faddl	MO(f5)			/* f5+(f6+f7*xm)*xm : xm */
+			sarl	$31, %eax
+	fmul	%st(1)			/* (f5+(f6+f7*xm)*xm)*xm : xm */
+			subl	%eax, %edx
+	faddl	MO(f4)			/* f4+(f5+(f6+f7*xm)*xm)*xm : xm */
+	fmul	%st(1)			/* (f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
+	faddl	MO(f3)			/* f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
+	fmul	%st(1)			/* (f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
+	faddl	MO(f2)			/* f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
+	fmul	%st(1)			/* (f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
+	faddl	MO(f1)			/* u:=f1+(f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
+
+	fld	%st			/* u : u : xm */
+	fmul	%st(1)			/* u*u : u : xm */
+	fld	%st(2)			/* xm : u*u : u : xm */
+	fadd	%st			/* 2*xm : u*u : u : xm */
+	fxch	%st(1)			/* u*u : 2*xm : u : xm */
+	fmul	%st(2)			/* t2:=u*u*u : 2*xm : u : xm */
+			movl	%edx, %eax
+	fadd	%st, %st(1)		/* t2 : t2+2*xm : u : xm */
+			leal	(%edx,%edx,2),%edx
+	fadd	%st(0)			/* 2*t2 : t2+2*xm : u : xm */
+			subl	%edx, %ecx
+	faddp	%st, %st(3)		/* t2+2*xm : u : 2*t2+xm */
+			shll	$3, %ecx
+	fmulp				/* u*(t2+2*xm) : 2*t2+xm */
+	fdivp	%st, %st(1)		/* u*(t2+2*xm)/(2*t2+xm) */
+	fmull	MOX(16+factor,%ecx)	/* u*(t2+2*xm)/(2*t2+xm)*FACT */
+	pushl	%eax
+	fildl	(%esp)			/* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
+	fxch				/* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
+	fscale				/* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
+	popl	%edx
+#ifdef PIC
+	movl	12(%esp), %eax
+	popl	%ebx
+#else
+	movl	8(%esp), %eax
+#endif
+	testl	%eax, %eax
+	fstp	%st(1)
+	jns	4f
+	fchs
+4:	ret
+
+	/* Return the argument.  */
+1:	fldl	4(%esp)
+	ret
+END(__cbrt)
+weak_alias (__cbrt, cbrt)
diff --git a/sysdeps/i386/fpu/s_cbrtf.S b/sysdeps/i386/fpu/s_cbrtf.S
new file mode 100644
index 0000000000..a14e04ed2f
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cbrtf.S
@@ -0,0 +1,178 @@
+/* Compute cubic root of float value.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+        .section .rodata
+#else
+        .text
+#endif
+
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f3,@object)
+f3:	.double 0.191502161678719066
+        ASM_SIZE_DIRECTIVE(f3)
+        ASM_TYPE_DIRECTIVE(f2,@object)
+f2:	.double 0.697570460207922770
+        ASM_SIZE_DIRECTIVE(f2)
+        ASM_TYPE_DIRECTIVE(f1,@object)
+f1:	.double 0.492659620528969547
+        ASM_SIZE_DIRECTIVE(f1)
+
+#define CBRT2		1.2599210498948731648
+#define ONE_CBRT2	0.793700525984099737355196796584
+#define SQR_CBRT2	1.5874010519681994748
+#define ONE_SQR_CBRT2	0.629960524947436582364439673883
+
+	ASM_TYPE_DIRECTIVE(factor,@object)
+        .align ALIGNARG(4)
+factor:	.double ONE_SQR_CBRT2
+	.double ONE_CBRT2
+	.double 1.0
+	.double CBRT2
+	.double SQR_CBRT2
+	ASM_SIZE_DIRECTIVE(factor)
+
+        ASM_TYPE_DIRECTIVE(two25,@object)
+two25:	.byte 0, 0, 0, 0x4c
+        ASM_SIZE_DIRECTIVE(two25)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ebx)
+#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
+#else
+#define MO(op) op
+#define MOX(op,x) op(x)
+#endif
+
+	.text
+ENTRY(__cbrtf)
+	movl	4(%esp), %eax
+	xorl	%ecx, %ecx
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+	jz	1f
+	cmpl	$0x7f800000, %eax
+	jae	1f
+
+#ifdef PIC
+	pushl	%ebx
+	call	3f
+3:	popl	%ebx
+	addl    $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
+#endif
+
+	cmpl	$0x00800000, %eax
+	jae	2f
+
+#ifdef PIC
+	flds	8(%esp)
+#else
+	flds	4(%esp)
+#endif
+	fmuls	MO(two25)
+	movl	$-25, %ecx
+#ifdef PIC
+	fstps	8(%esp)
+	movl	8(%esp), %eax
+#else
+	fstps	4(%esp)
+	movl	4(%esp), %eax
+#endif
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+
+2:	shrl	$23, %eax
+	andl	$0x807fffff, %edx
+	subl	$126, %eax
+	orl	$0x3f000000, %edx
+	addl	%eax, %ecx
+#ifdef PIC
+	movl	%edx, 8(%esp)
+
+	flds	8(%esp)			/* xm */
+#else
+	movl	%edx, 4(%esp)
+
+	flds	4(%esp)			/* xm */
+#endif
+	fabs
+
+	/* The following code has two tracks:
+	    a) compute the normalized cbrt value
+	    b) compute xe/3 and xe%3
+	   The right track computes the value for b) and this is done
+	   in an optimized way by avoiding division.
+
+	   But why two tracks at all?  Very easy: efficiency.  Some FP
+	   instruction can overlap with a certain amount of integer (and
+	   FP) instructions.  So we get (except for the imull) all
+	   instructions for free.  */
+
+	fld	%st(0)			/* xm : xm */
+	fmull	MO(f3)			/* f3*xm : xm */
+			movl	$1431655766, %eax
+	fsubrl	MO(f2)			/* f2-f3*xm : xm */
+			imull	%ecx
+	fmul	%st(1)			/* (f2-f3*xm)*xm : xm */
+			movl	%ecx, %eax
+	faddl	MO(f1)			/* u:=f1+(f2-f3*xm)*xm : xm */
+			sarl	$31, %eax
+	fld	%st			/* u : u : xm */
+			subl	%eax, %edx
+	fmul	%st(1)			/* u*u : u : xm */
+	fld	%st(2)			/* xm : u*u : u : xm */
+	fadd	%st			/* 2*xm : u*u : u : xm */
+	fxch	%st(1)			/* u*u : 2*xm : u : xm */
+	fmul	%st(2)			/* t2:=u*u*u : 2*xm : u : xm */
+			movl	%edx, %eax
+	fadd	%st, %st(1)		/* t2 : t2+2*xm : u : xm */
+			leal	(%edx,%edx,2),%edx
+	fadd	%st(0)			/* 2*t2 : t2+2*xm : u : xm */
+			subl	%edx, %ecx
+	faddp	%st, %st(3)		/* t2+2*xm : u : 2*t2+xm */
+			shll	$3, %ecx
+	fmulp				/* u*(t2+2*xm) : 2*t2+xm */
+	fdivp	%st, %st(1)		/* u*(t2+2*xm)/(2*t2+xm) */
+	fmull	MOX(16+factor,%ecx)	/* u*(t2+2*xm)/(2*t2+xm)*FACT */
+	pushl	%eax
+	fildl	(%esp)			/* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
+	fxch				/* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
+	fscale				/* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
+	popl	%edx
+#ifdef PIC
+	movl	8(%esp), %eax
+	popl	%ebx
+#else
+	movl	4(%esp), %eax
+#endif
+	testl	%eax, %eax
+	fstp	%st(1)
+	jns	4f
+	fchs
+4:	ret
+
+	/* Return the argument.  */
+1:	flds	4(%esp)
+	ret
+END(__cbrtf)
+weak_alias (__cbrtf, cbrtf)
diff --git a/sysdeps/i386/fpu/s_cbrtl.S b/sysdeps/i386/fpu/s_cbrtl.S
new file mode 100644
index 0000000000..6a3b9a8dc5
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cbrtl.S
@@ -0,0 +1,229 @@
+/* Compute cubic root of long double value.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+   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 <machine/asm.h>
+
+#ifdef __ELF__
+        .section .rodata
+#else
+        .text
+#endif
+
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f8,@object)
+f8:	.tfloat 0.161617097923756032
+	ASM_SIZE_DIRECTIVE(f8)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f7,@object)
+f7:	.tfloat -0.988553671195413709
+	ASM_SIZE_DIRECTIVE(f7)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f6,@object)
+f6:	.tfloat 2.65298938441952296
+	ASM_SIZE_DIRECTIVE(f6)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f5,@object)
+f5:	.tfloat -4.11151425200350531
+	ASM_SIZE_DIRECTIVE(f5)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f4,@object)
+f4:	.tfloat 4.09559907378707839
+	ASM_SIZE_DIRECTIVE(f4)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f3,@object)
+f3:	.tfloat -2.82414939754975962
+	ASM_SIZE_DIRECTIVE(f3)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f2,@object)
+f2:	.tfloat 1.67595307700780102
+	ASM_SIZE_DIRECTIVE(f2)
+        .align ALIGNARG(4)
+        ASM_TYPE_DIRECTIVE(f1,@object)
+f1:	.tfloat 0.338058687610520237
+	ASM_SIZE_DIRECTIVE(f1)
+
+#define CBRT2		1.2599210498948731648
+#define ONE_CBRT2	0.793700525984099737355196796584
+#define SQR_CBRT2	1.5874010519681994748
+#define ONE_SQR_CBRT2	0.629960524947436582364439673883
+
+	/* We make the entries in the following table all 16 bytes
+	   wide to avoid having to implement a multiplication by 10.  */
+	ASM_TYPE_DIRECTIVE(factor,@object)
+        .align ALIGNARG(4)
+factor:	.tfloat ONE_SQR_CBRT2
+	.byte 0, 0, 0, 0, 0, 0
+	.tfloat ONE_CBRT2
+	.byte 0, 0, 0, 0, 0, 0
+	.tfloat 1.0
+	.byte 0, 0, 0, 0, 0, 0
+	.tfloat CBRT2
+	.byte 0, 0, 0, 0, 0, 0
+	.tfloat SQR_CBRT2
+	ASM_SIZE_DIRECTIVE(factor)
+
+        ASM_TYPE_DIRECTIVE(two64,@object)
+        .align ALIGNARG(4)
+two64:  .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
+        ASM_SIZE_DIRECTIVE(two64)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ebx)
+#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
+#else
+#define MO(op) op
+#define MOX(op,x) op(x)
+#endif
+
+	.text
+ENTRY(__cbrtl)
+	movl	4(%esp), %ecx
+	movl	12(%esp), %eax
+	orl	8(%esp), %ecx
+	movl	%eax, %edx
+	andl	$0x7fff, %eax
+	orl	%eax, %ecx
+	jz	1f
+	xorl	%ecx, %ecx
+	cmpl	$0x7fff, %eax
+	je	1f
+
+#ifdef PIC
+	pushl	%ebx
+	call	3f
+3:	popl	%ebx
+	addl    $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
+#endif
+
+	cmpl	$0, %eax
+	jne	2f
+
+#ifdef PIC
+	fldt	8(%esp)
+#else
+	fldt	4(%esp)
+#endif
+	fmull	MO(two64)
+	movl	$-64, %ecx
+#ifdef PIC
+	fstpt	8(%esp)
+	movl	16(%esp), %eax
+#else
+	fstpt	4(%esp)
+	movl	12(%esp), %eax
+#endif
+	movl	%eax, %edx
+	andl	$0x7fff, %eax
+
+2:	andl	$0x8000, %edx
+	subl	$16382, %eax
+	orl	$0x3ffe, %edx
+	addl	%eax, %ecx
+#ifdef PIC
+	movl	%edx, 16(%esp)
+
+	fldt	8(%esp)			/* xm */
+#else
+	movl	%edx, 12(%esp)
+
+	fldt	4(%esp)			/* xm */
+#endif
+	fabs
+
+	/* The following code has two tracks:
+	    a) compute the normalized cbrt value
+	    b) compute xe/3 and xe%3
+	   The right track computes the value for b) and this is done
+	   in an optimized way by avoiding division.
+
+	   But why two tracks at all?  Very easy: efficiency.  Some FP
+	   instruction can overlap with a certain amount of integer (and
+	   FP) instructions.  So we get (except for the imull) all
+	   instructions for free.  */
+
+	fldt	MO(f8)			/* f8 : xm */
+	fmul	%st(1)			/* f8*xm : xm */
+
+	fldt	MO(f7)
+	faddp				/* f7+f8*xm : xm */
+	fmul	%st(1)			/* (f7+f8*xm)*xm : xm */
+			movl	$1431655766, %eax
+	fldt	MO(f6)
+	faddp				/* f6+(f7+f8*xm)*xm : xm */
+			imull	%ecx
+	fmul	%st(1)			/* (f6+(f7+f8*xm)*xm)*xm : xm */
+			movl	%ecx, %eax
+	fldt	MO(f5)
+	faddp				/* f5+(f6+(f7+f8*xm)*xm)*xm : xm */
+			sarl	$31, %eax
+	fmul	%st(1)			/* (f5+(f6+(f7+f8*xm)*xm)*xm)*xm : xm */
+			subl	%eax, %edx
+	fldt	MO(f4)
+	faddp				/* f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm : xm */
+	fmul	%st(1)			/* (f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm : xm */
+	fldt	MO(f3)
+	faddp				/* f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm : xm */
+	fmul	%st(1)			/* (f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm : xm */
+	fldt	MO(f2)
+	faddp				/* f2+(f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm : xm */
+	fmul	%st(1)			/* (f2+(f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm)*xm : xm */
+	fldt	MO(f1)
+	faddp				/* u:=f1+(f2+(f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm)*xm : xm */
+
+	fld	%st			/* u : u : xm */
+	fmul	%st(1)			/* u*u : u : xm */
+	fld	%st(2)			/* xm : u*u : u : xm */
+	fadd	%st			/* 2*xm : u*u : u : xm */
+	fxch	%st(1)			/* u*u : 2*xm : u : xm */
+	fmul	%st(2)			/* t2:=u*u*u : 2*xm : u : xm */
+			movl	%edx, %eax
+	fadd	%st, %st(1)		/* t2 : t2+2*xm : u : xm */
+			leal	(%edx,%edx,2),%edx
+	fadd	%st(0)			/* 2*t2 : t2+2*xm : u : xm */
+			subl	%edx, %ecx
+	faddp	%st, %st(3)		/* t2+2*xm : u : 2*t2+xm */
+			shll	$4, %ecx
+	fmulp				/* u*(t2+2*xm) : 2*t2+xm */
+	fdivp	%st, %st(1)		/* u*(t2+2*xm)/(2*t2+xm) */
+	fldt	MOX(32+factor,%ecx)
+	fmulp				/* u*(t2+2*xm)/(2*t2+xm)*FACT */
+	pushl	%eax
+	fildl	(%esp)			/* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
+	fxch				/* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
+	fscale				/* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
+	popl	%edx
+#ifdef PIC
+	movl	16(%esp), %eax
+	popl	%ebx
+#else
+	movl	12(%esp), %eax
+#endif
+	testl	$0x8000, %eax
+	fstp	%st(1)
+	jz	4f
+	fchs
+4:	ret
+
+	/* Return the argument.  */
+1:	fldt	4(%esp)
+	ret
+END(__cbrtl)
+weak_alias (__cbrtl, cbrtl)
diff --git a/sysdeps/i386/fpu/s_ceil.S b/sysdeps/i386/fpu/s_ceil.S
new file mode 100644
index 0000000000..b0159128aa
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ceil.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ceil.S,v 1.4 1995/05/08 23:52:13 jtc Exp $")
+
+ENTRY(__ceil)
+	fldl	4(%esp)
+	subl	$8,%esp
+
+	fstcw	4(%esp)			/* store fpu control word */
+
+	/* We use here %edx although only the low 1 bits are defined.
+	   But none of the operations should care and they are faster
+	   than the 16 bit operations.  */
+	movl	$0x0800,%edx		/* round towards +oo */
+	orl	4(%esp),%edx
+	andl	$0xfbff,%edx
+	movl	%edx,(%esp)
+	fldcw	(%esp)			/* load modified control word */
+
+	frndint				/* round */
+
+	fldcw	4(%esp)			/* restore original control word */
+
+	addl	$8,%esp
+	ret
+END (__ceil)
+weak_alias (__ceil, ceil)
diff --git a/sysdeps/i386/fpu/s_ceilf.S b/sysdeps/i386/fpu/s_ceilf.S
new file mode 100644
index 0000000000..352d40d7ce
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ceilf.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ceilf.S,v 1.3 1995/05/08 23:52:44 jtc Exp $")
+
+ENTRY(__ceilf)
+	flds	4(%esp)
+	subl	$8,%esp
+
+	fstcw	4(%esp)			/* store fpu control word */
+
+	/* We use here %edx although only the low 1 bits are defined.
+	   But none of the operations should care and they are faster
+	   than the 16 bit operations.  */
+	movl	$0x0800,%edx		/* round towards +oo */
+	orl	4(%esp),%edx
+	andl	$0xfbff,%edx
+	movl	%edx,(%esp)
+	fldcw	(%esp)			/* load modified control word */
+
+	frndint				/* round */
+
+	fldcw	4(%esp)			/* restore original control word */
+
+	addl	$8,%esp
+	ret
+END (__ceilf)
+weak_alias (__ceilf, ceilf)
diff --git a/sysdeps/i386/fpu/s_ceill.S b/sysdeps/i386/fpu/s_ceill.S
new file mode 100644
index 0000000000..0128966ebe
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ceill.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ceill)
+	fldt	4(%esp)
+	subl	$8,%esp
+
+	fstcw	4(%esp)			/* store fpu control word */
+
+	/* We use here %edx although only the low 1 bits are defined.
+	   But none of the operations should care and they are faster
+	   than the 16 bit operations.  */
+	movl	$0x0800,%edx		/* round towards +oo */
+	orl	4(%esp),%edx
+	andl	$0xfbff,%edx
+	movl	%edx,(%esp)
+	fldcw	(%esp)			/* load modified control word */
+
+	frndint				/* round */
+
+	fldcw	4(%esp)			/* restore original control word */
+
+	addl	$8,%esp
+	ret
+END (__ceill)
+weak_alias (__ceill, ceill)
diff --git a/sysdeps/i386/fpu/s_cexp.S b/sysdeps/i386/fpu/s_cexp.S
new file mode 100644
index 0000000000..61158d9540
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cexp.S
@@ -0,0 +1,259 @@
+/* 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
+zero:	.double	0.0
+infinity:
+	.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	20f
+
+	/* 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
+	testb	$0x01, %ah	/* See above why 0x01 is usable here.  */
+	jne	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> */
+	andb	$0x45, %ah
+	andb	$0x47, %dh
+	xorb	%dh, %ah
+	jnz	30f
+	fldl	MO(infinity)	/* Raise invalid exception.  */
+	fmull	MO(zero)
+	fstp	%st(0)
+30:	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)
+	fxch
+	fstpl	(%eax)
+	fstpl	8(%eax)
+	ret	$4
+
+	/* The real part is NaN.  */
+	.align ALIGNARG(4)
+20:	fldl	MO(infinity)		/* Raise invalid exception.  */
+	fmull	MO(zero)
+	fstp	%st(0)
+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/i386/fpu/s_cexpf.S b/sysdeps/i386/fpu/s_cexpf.S
new file mode 100644
index 0000000000..d6dcebcb23
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cexpf.S
@@ -0,0 +1,255 @@
+/* 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
+zero:	.float	0.0
+infinity:
+	.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	20f
+
+	/* 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
+	testb	$0x01, %ah	/* See above why 0x01 is usable here.  */
+	jne	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> */
+	andb	$0x45, %ah
+	andb	$0x47, %dh
+	xorb	%dh, %ah
+	jnz	30f
+	flds	MO(infinity)	/* Raise invalid exception.  */
+	fmuls	MO(zero)
+	fstp	%st(0)
+30:	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)
+20:	flds	MO(infinity)		/* Raise invalid exception.  */
+	fmuls	MO(zero)
+	fstp	%st(0)
+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/i386/fpu/s_cexpl.S b/sysdeps/i386/fpu/s_cexpl.S
new file mode 100644
index 0000000000..203a7ee779
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cexpl.S
@@ -0,0 +1,262 @@
+/* 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
+zero:	.double	0.0
+infinity:
+	.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	20f
+
+	/* 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
+	testb	$0x01, %ah	/* See above why 0x01 is usable here.  */
+	jne	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.  */
+	fld	%st
+	fstpt	12(%edx)
+	fstpt	(%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.  */
+	fld	%st
+	fstpt	12(%edx)
+	fstpt	(%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> */
+	andb	$0x45, %ah
+	andb	$0x47, %dh
+	xorb	%dh, %ah
+	jnz	30f
+	fldl	MO(infinity)	/* Raise invalid exception.  */
+	fmull	MO(zero)
+	fstp	%st(0)
+30:	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)
+	fxch
+	fstpt	(%eax)
+	fstpt	12(%eax)
+	ret	$4
+
+	/* The real part is NaN.  */
+	.align ALIGNARG(4)
+20:	fldl	MO(infinity)		/* Raise invalid exception.  */
+	fmull	MO(zero)
+	fstp	%st(0)
+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/i386/fpu/s_copysign.S b/sysdeps/i386/fpu/s_copysign.S
new file mode 100644
index 0000000000..2520a94427
--- /dev/null
+++ b/sysdeps/i386/fpu/s_copysign.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_copysign.S,v 1.4 1995/05/08 23:53:02 jtc Exp $")
+
+ENTRY(__copysign)
+	movl	16(%esp),%edx
+	movl	8(%esp),%eax
+	andl	$0x80000000,%edx
+	andl	$0x7fffffff,%eax
+	orl	%edx,%eax
+	movl	%eax,8(%esp)
+	fldl	4(%esp)
+	ret
+END (__copysign)
+weak_alias (__copysign, copysign)
diff --git a/sysdeps/i386/fpu/s_copysignf.S b/sysdeps/i386/fpu/s_copysignf.S
new file mode 100644
index 0000000000..57b1a6f119
--- /dev/null
+++ b/sysdeps/i386/fpu/s_copysignf.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_copysignf.S,v 1.3 1995/05/08 23:53:25 jtc Exp $")
+
+ENTRY(__copysignf)
+	movl	8(%esp),%edx
+	movl	4(%esp),%eax
+	andl	$0x80000000,%edx
+	andl	$0x7fffffff,%eax
+	orl	%edx,%eax
+	movl	%eax,4(%esp)
+	flds	4(%esp)
+	ret
+END (__copysignf)
+weak_alias (__copysignf, copysignf)
diff --git a/sysdeps/i386/fpu/s_copysignl.S b/sysdeps/i386/fpu/s_copysignl.S
new file mode 100644
index 0000000000..2163e7b014
--- /dev/null
+++ b/sysdeps/i386/fpu/s_copysignl.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__copysignl)
+	movl	24(%esp),%edx
+	movl	12(%esp),%eax
+	andl	$0x8000,%edx
+	andl	$0x7fff,%eax
+	orl	%edx,%eax
+	movl	%eax,12(%esp)
+	fldt	4(%esp)
+	ret
+END (__copysignl)
+weak_alias (__copysignl, copysignl)
diff --git a/sysdeps/i386/fpu/s_cos.S b/sysdeps/i386/fpu/s_cos.S
new file mode 100644
index 0000000000..ac8b1459d9
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cos.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_cos.S,v 1.5 1995/05/08 23:54:00 jtc Exp $")
+
+ENTRY(__cos)
+	fldl	4(%esp)
+	fcos
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fcos
+	ret
+END (__cos)
+weak_alias (__cos, cos)
diff --git a/sysdeps/i386/fpu/s_cosf.S b/sysdeps/i386/fpu/s_cosf.S
new file mode 100644
index 0000000000..d8e8090639
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cosf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_cosf.S,v 1.3 1995/05/08 23:55:16 jtc Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(__cosf)
+	flds	4(%esp)
+	fcos
+	ret
+END (__cosf)
+weak_alias (__cosf, cosf)
diff --git a/sysdeps/i386/fpu/s_cosl.S b/sysdeps/i386/fpu/s_cosl.S
new file mode 100644
index 0000000000..61c9010c99
--- /dev/null
+++ b/sysdeps/i386/fpu/s_cosl.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__cosl)
+	fldt	4(%esp)
+	fcos
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fcos
+	ret
+END (__cosl)
+weak_alias (__cosl, cosl)
diff --git a/sysdeps/i386/fpu/s_exp2.S b/sysdeps/i386/fpu/s_exp2.S
new file mode 100644
index 0000000000..778c0c0eb6
--- /dev/null
+++ b/sysdeps/i386/fpu/s_exp2.S
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2)
+	fldl	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fld	%st
+	frndint				/* int(x) */
+	fsubr	%st,%st(1)		/* fract(x) */
+	fxch
+	f2xm1				/* 2^(fract(x)) - 1 */
+	fld1
+	faddp				/* 2^(fract(x)) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+1:	testl	$0x200, %eax		/* Test sign.  */
+	jz	2f			/* If positive, jump.  */
+	fstp	%st
+	fldz				/* Set result to 0.  */
+2:	ret
+END (__ieee754_exp2)
diff --git a/sysdeps/i386/fpu/s_exp2f.S b/sysdeps/i386/fpu/s_exp2f.S
new file mode 100644
index 0000000000..c2d1af1af1
--- /dev/null
+++ b/sysdeps/i386/fpu/s_exp2f.S
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2f)
+	flds	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fld	%st
+	frndint				/* int(x) */
+	fsubr	%st,%st(1)		/* fract(x) */
+	fxch
+	f2xm1				/* 2^(fract(x)) - 1 */
+	fld1
+	faddp				/* 2^(fract(x)) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+1:	testl	$0x200, %eax		/* Test sign.  */
+	jz	2f			/* If positive, jump.  */
+	fstp	%st
+	fldz				/* Set result to 0.  */
+2:	ret
+END (__ieee754_exp2f)
diff --git a/sysdeps/i386/fpu/s_exp2l.S b/sysdeps/i386/fpu/s_exp2l.S
new file mode 100644
index 0000000000..fa1fdc9236
--- /dev/null
+++ b/sysdeps/i386/fpu/s_exp2l.S
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2l)
+	fldt	4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+   in NaN.  The ugliness results from the bright minds at Intel.
+   For the i686 the code can be written better.
+   -- drepper@cygnus.com.  */
+	fxam				/* Is NaN or +-Inf?  */
+	fstsw	%ax
+	movb	$0x45, %dh
+	andb	%ah, %dh
+	cmpb	$0x05, %dh
+	je	1f			/* Is +-Inf, jump.  */
+	fld	%st
+	frndint				/* int(x) */
+	fsubr	%st,%st(1)		/* fract(x) */
+	fxch
+	f2xm1				/* 2^(fract(x)) - 1 */
+	fld1
+	faddp				/* 2^(fract(x)) */
+	fscale				/* e^x */
+	fstp	%st(1)
+	ret
+
+1:	testl	$0x200, %eax		/* Test sign.  */
+	jz	2f			/* If positive, jump.  */
+	fstp	%st
+	fldz				/* Set result to 0.  */
+2:	ret
+END (__ieee754_exp2l)
diff --git a/sysdeps/i386/fpu/s_expm1.S b/sysdeps/i386/fpu/s_expm1.S
new file mode 100644
index 0000000000..92beaf0776
--- /dev/null
+++ b/sysdeps/i386/fpu/s_expm1.S
@@ -0,0 +1,88 @@
+/* ix87 specific implementation of exp(x)-1.
+   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.
+   Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+   Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 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.  */
+
+	/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	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)
+	ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:	.tfloat 1.442695040888963407359924681002
+	ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__expm1)
+	fldl	4(%esp)		// x
+	fxam			// Is NaN or +-Inf?
+	fstsw	%ax
+	movb	$0x45, %ch
+	andb	%ah, %ch
+	cmpb	$0x40, %ch
+	je	3f		// If +-0, jump.
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpb	$0x05, %ch
+	je	2f		// If +-Inf, jump.
+
+	fldt	MO(l2e)		// log2(e) : x
+	fmulp			// log2(e)*x
+	fld	%st		// log2(e)*x : log2(e)*x
+	frndint			// int(log2(e)*x) : log2(e)*x
+	fsubr	%st, %st(1)	// int(log2(e)*x) : fract(log2(e)*x)
+	fxch			// fract(log2(e)*x) : int(log2(e)*x)
+	f2xm1			// 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+	fscale			// 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+	fxch			// int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fldl	MO(one)		// 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fscale			// 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fsubrl	MO(one)		// 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fstp	%st(1)		// 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fsubrp	%st, %st(1)	// 2^(log2(e)*x)
+	ret
+
+2:	testl	$0x200, %eax	// Test sign.
+	jz	3f		// If positive, jump.
+	fstp	%st
+	fldl	MO(minus1)	// Set result to -1.0.
+3:	ret
+END(__expm1)
+weak_alias (__expm1, expm1)
diff --git a/sysdeps/i386/fpu/s_expm1f.S b/sysdeps/i386/fpu/s_expm1f.S
new file mode 100644
index 0000000000..45a60fe010
--- /dev/null
+++ b/sysdeps/i386/fpu/s_expm1f.S
@@ -0,0 +1,88 @@
+/* ix87 specific implementation of exp(x)-1.
+   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.
+   Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+   Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 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.  */
+
+	/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	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)
+	ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:	.tfloat 1.442695040888963407359924681002
+	ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__expm1f)
+	flds	4(%esp)		// x
+	fxam			// Is NaN or +-Inf?
+	fstsw	%ax
+	movb	$0x45, %ch
+	andb	%ah, %ch
+	cmpb	$0x40, %ch
+	je	3f		// If +-0, jump.
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpb	$0x05, %ch
+	je	2f		// If +-Inf, jump.
+
+	fldt	MO(l2e)		// log2(e) : x
+	fmulp			// log2(e)*x
+	fld	%st		// log2(e)*x : log2(e)*x
+	frndint			// int(log2(e)*x) : log2(e)*x
+	fsubr	%st, %st(1)	// int(log2(e)*x) : fract(log2(e)*x)
+	fxch			// fract(log2(e)*x) : int(log2(e)*x)
+	f2xm1			// 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+	fscale			// 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+	fxch			// int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fldl	MO(one)		// 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fscale			// 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fsubrl	MO(one)		// 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fstp	%st(1)		// 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fsubrp	%st, %st(1)	// 2^(log2(e)*x)
+	ret
+
+2:	testl	$0x200, %eax	// Test sign.
+	jz	3f		// If positive, jump.
+	fstp	%st
+	fldl	MO(minus1)	// Set result to -1.0.
+3:	ret
+END(__expm1f)
+weak_alias (__expm1f, expm1f)
diff --git a/sysdeps/i386/fpu/s_expm1l.S b/sysdeps/i386/fpu/s_expm1l.S
new file mode 100644
index 0000000000..13fa698cc7
--- /dev/null
+++ b/sysdeps/i386/fpu/s_expm1l.S
@@ -0,0 +1,88 @@
+/* ix87 specific implementation of exp(x)-1.
+   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.
+   Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+   Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 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.  */
+
+	/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	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)
+	ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:	.tfloat 1.442695040888963407359924681002
+	ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__expm1l)
+	fldt	4(%esp)		// x
+	fxam			// Is NaN or +-Inf?
+	fstsw	%ax
+	movb	$0x45, %ch
+	andb	%ah, %ch
+	cmpb	$0x40, %ch
+	je	3f		// If +-0, jump.
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	cmpb	$0x05, %ch
+	je	2f		// If +-Inf, jump.
+
+	fldt	MO(l2e)		// log2(e) : x
+	fmulp			// log2(e)*x
+	fld	%st		// log2(e)*x : log2(e)*x
+	frndint			// int(log2(e)*x) : log2(e)*x
+	fsubr	%st, %st(1)	// int(log2(e)*x) : fract(log2(e)*x)
+	fxch			// fract(log2(e)*x) : int(log2(e)*x)
+	f2xm1			// 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+	fscale			// 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+	fxch			// int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fldl	MO(one)		// 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fscale			// 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fsubrl	MO(one)		// 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fstp	%st(1)		// 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+	fsubrp	%st, %st(1)	// 2^(log2(e)*x)
+	ret
+
+2:	testl	$0x200, %eax	// Test sign.
+	jz	3f		// If positive, jump.
+	fstp	%st
+	fldl	MO(minus1)	// Set result to -1.0.
+3:	ret
+END(__expm1l)
+weak_alias (__expm1l, expm1l)
diff --git a/sysdeps/i386/fpu/s_fdim.S b/sysdeps/i386/fpu/s_fdim.S
new file mode 100644
index 0000000000..7a1e2ffa49
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fdim.S
@@ -0,0 +1,51 @@
+/* Compute positive difference.
+   Copyright (C) 1997, 1999 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>
+
+	.text
+ENTRY(__fdim)
+	fldl	4(%esp)		// x
+	fldl	12(%esp)	// x : y
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jp	1f
+
+	fsubrp	%st, %st(1)
+	jc	2f
+
+	fstp	%st(0)
+	fldz
+	jmp	2f
+
+1:	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	3f
+
+	fxch
+3:	fstp	%st(1)
+
+2:	ret
+END(__fdim)
+weak_alias (__fdim, fdim)
diff --git a/sysdeps/i386/fpu/s_fdimf.S b/sysdeps/i386/fpu/s_fdimf.S
new file mode 100644
index 0000000000..7e58f6752b
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fdimf.S
@@ -0,0 +1,51 @@
+/* Compute positive difference.
+   Copyright (C) 1997, 1999 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>
+
+	.text
+ENTRY(__fdimf)
+	flds	4(%esp)		// x
+	flds	8(%esp)		// x : y
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jp	1f
+
+	fsubrp	%st, %st(1)
+	jc	2f
+
+	fstp	%st(0)
+	fldz
+	jmp	2f
+
+1:	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	3f
+
+	fxch
+3:	fstp	%st(1)
+
+2:	ret
+END(__fdimf)
+weak_alias (__fdimf, fdimf)
diff --git a/sysdeps/i386/fpu/s_fdiml.S b/sysdeps/i386/fpu/s_fdiml.S
new file mode 100644
index 0000000000..7a8c18a5d3
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fdiml.S
@@ -0,0 +1,51 @@
+/* Compute positive difference.
+   Copyright (C) 1997, 1999 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>
+
+	.text
+ENTRY(__fdiml)
+	fldt	4(%esp)		// x
+	fldt	16(%esp)	// x : y
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jp	1f
+
+	fsubrp	%st, %st(1)
+	jc	2f
+
+	fstp	%st(0)
+	fldz
+	jmp	2f
+
+1:	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	3f
+
+	fxch
+3:	fstp	%st(1)
+
+2:	ret
+END(__fdiml)
+weak_alias (__fdiml, fdiml)
diff --git a/sysdeps/i386/fpu/s_finite.S b/sysdeps/i386/fpu/s_finite.S
new file mode 100644
index 0000000000..63c766a950
--- /dev/null
+++ b/sysdeps/i386/fpu/s_finite.S
@@ -0,0 +1,15 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finite)
+	movl	8(%esp),%eax
+	movl    $0xFFEFFFFF,%ecx
+	subl    %eax,%ecx
+	xorl    %ecx,%eax
+	shrl	$31, %eax
+	ret
+END (__finite)
+weak_alias (__finite, finite)
diff --git a/sysdeps/i386/fpu/s_finitef.S b/sysdeps/i386/fpu/s_finitef.S
new file mode 100644
index 0000000000..dabb71a115
--- /dev/null
+++ b/sysdeps/i386/fpu/s_finitef.S
@@ -0,0 +1,15 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finitef)
+	movl	4(%esp),%eax
+	movl    $0xFF7FFFFF,%ecx
+	subl    %eax,%ecx
+	xorl    %ecx,%eax
+	shrl    $31,%eax
+	ret
+END (__finitef)
+weak_alias (__finitef, finitef)
diff --git a/sysdeps/i386/fpu/s_finitel.S b/sysdeps/i386/fpu/s_finitel.S
new file mode 100644
index 0000000000..acc5ad4cd0
--- /dev/null
+++ b/sysdeps/i386/fpu/s_finitel.S
@@ -0,0 +1,14 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finitel)
+	movl	12(%esp),%eax
+	orl	$0xffff8000, %eax
+	incl	%eax
+	shrl	$31, %eax
+	ret
+END (__finitel)
+weak_alias (__finitel, finitel)
diff --git a/sysdeps/i386/fpu/s_floor.S b/sysdeps/i386/fpu/s_floor.S
new file mode 100644
index 0000000000..20a8660424
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floor.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floor.S,v 1.4 1995/05/09 00:01:59 jtc Exp $")
+
+ENTRY(__floor)
+	fldl	4(%esp)
+	subl	$8,%esp
+
+	fstcw	4(%esp)			/* store fpu control word */
+
+	/* We use here %edx although only the low 1 bits are defined.
+	   But none of the operations should care and they are faster
+	   than the 16 bit operations.  */
+	movl	$0x400,%edx		/* round towards -oo */
+	orl	4(%esp),%edx
+	andl	$0xf7ff,%edx
+	movl	%edx,(%esp)
+	fldcw	(%esp)			/* load modified control word */
+
+	frndint				/* round */
+
+	fldcw	4(%esp)			/* restore original control word */
+
+	addl	$8,%esp
+	ret
+END (__floor)
+weak_alias (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floorf.S b/sysdeps/i386/fpu/s_floorf.S
new file mode 100644
index 0000000000..eca93a2aa3
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floorf.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $")
+
+ENTRY(__floorf)
+	flds	4(%esp)
+	subl	$8,%esp
+
+	fstcw	4(%esp)			/* store fpu control word */
+
+	/* We use here %edx although only the low 1 bits are defined.
+	   But none of the operations should care and they are faster
+	   than the 16 bit operations.  */
+	movl	$0x400,%edx		/* round towards -oo */
+	orl	4(%esp),%edx
+	andl	$0xf7ff,%edx
+	movl	%edx,(%esp)
+	fldcw	(%esp)			/* load modified control word */
+
+	frndint				/* round */
+
+	fldcw	4(%esp)			/* restore original control word */
+
+	addl	$8,%esp
+	ret
+END (__floorf)
+weak_alias (__floorf, floorf)
diff --git a/sysdeps/i386/fpu/s_floorl.S b/sysdeps/i386/fpu/s_floorl.S
new file mode 100644
index 0000000000..c2bf091d73
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floorl.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__floorl)
+	fldt	4(%esp)
+	subl	$8,%esp
+
+	fstcw	4(%esp)			/* store fpu control word */
+
+	/* We use here %edx although only the low 1 bits are defined.
+	   But none of the operations should care and they are faster
+	   than the 16 bit operations.  */
+	movl	$0x400,%edx		/* round towards -oo */
+	orl	4(%esp),%edx
+	andl	$0xf7ff,%edx
+	movl	%edx,(%esp)
+	fldcw	(%esp)			/* load modified control word */
+
+	frndint				/* round */
+
+	fldcw	4(%esp)			/* restore original control word */
+
+	addl	$8,%esp
+	ret
+END (__floorl)
+weak_alias (__floorl, floorl)
diff --git a/sysdeps/i386/fpu/s_fma.S b/sysdeps/i386/fpu/s_fma.S
new file mode 100644
index 0000000000..2affafcbf5
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fma.S
@@ -0,0 +1,31 @@
+/* Compute (X * Y) + Z as ternary operation.
+   Copyright (C) 1997, 1998 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>
+
+	.text
+ENTRY(__fma)
+	fldl	4(%esp)		// x
+	fmull	12(%esp)	// x * y
+	fldl	20(%esp)	// z : x * y
+	faddp			// (x * y) + z
+	ret
+END(__fma)
+weak_alias (__fma, fma)
diff --git a/sysdeps/i386/fpu/s_fmaf.S b/sysdeps/i386/fpu/s_fmaf.S
new file mode 100644
index 0000000000..03c6cc0f9e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fmaf.S
@@ -0,0 +1,31 @@
+/* Compute (X * Y) + Z as ternary operation.
+   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>
+
+	.text
+ENTRY(__fmaf)
+	flds	4(%esp)		// x
+	fmuls	8(%esp)		// x * y
+	flds	12(%esp)	// z : x * y
+	faddp			// (x * y) + z
+	ret
+END(__fmaf)
+weak_alias (__fmaf, fmaf)
diff --git a/sysdeps/i386/fpu/s_fmal.S b/sysdeps/i386/fpu/s_fmal.S
new file mode 100644
index 0000000000..c15fca8dab
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fmal.S
@@ -0,0 +1,32 @@
+/* Compute (X * Y) + Z as ternary operation.
+   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>
+
+	.text
+ENTRY(__fmal)
+	fldt	4(%esp)		// x
+	fldt	16(%esp)	// x : y
+	fmulp			// x * y
+	fldt	28(%esp)	// z : x * y
+	faddp			// (x * y) + z
+	ret
+END(__fmal)
+weak_alias (__fmal, fmal)
diff --git a/sysdeps/i386/fpu/s_fmax.S b/sysdeps/i386/fpu/s_fmax.S
new file mode 100644
index 0000000000..3dbaa139ad
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fmax.S
@@ -0,0 +1,44 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+   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>
+
+	.text
+ENTRY(__fmax)
+	fldl	12(%esp)	// y
+	fxam
+	fnstsw
+	fldl	4(%esp)		// y : x
+
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	1f		// y == NaN
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jnc	1f
+
+	fxch	%st(1)
+1:	fstp	%st(1)
+
+	ret
+END(__fmax)
+weak_alias (__fmax, fmax)
diff --git a/sysdeps/i386/fpu/s_fmaxf.S b/sysdeps/i386/fpu/s_fmaxf.S
new file mode 100644
index 0000000000..5dd94a43c4
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fmaxf.S
@@ -0,0 +1,44 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+   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>
+
+	.text
+ENTRY(__fmaxf)
+	flds	8(%esp)		// y
+	fxam
+	fnstsw
+	flds	4(%esp)		// y : x
+
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	1f		// y == NaN
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jnc	1f
+
+	fxch	%st(1)
+1:	fstp	%st(1)
+
+	ret
+END(__fmaxf)
+weak_alias (__fmaxf, fmaxf)
diff --git a/sysdeps/i386/fpu/s_fmaxl.S b/sysdeps/i386/fpu/s_fmaxl.S
new file mode 100644
index 0000000000..d833bd1985
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fmaxl.S
@@ -0,0 +1,44 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+   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>
+
+	.text
+ENTRY(__fmaxl)
+	fldt	16(%esp)	// y
+	fxam
+	fnstsw
+	fldt	4(%esp)		// y : x
+
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	1f		// y == NaN
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jnc	1f
+
+	fxch	%st(1)
+1:	fstp	%st(1)
+
+	ret
+END(__fmaxl)
+weak_alias (__fmaxl, fmaxl)
diff --git a/sysdeps/i386/fpu/s_fmin.S b/sysdeps/i386/fpu/s_fmin.S
new file mode 100644
index 0000000000..1ac46c7d21
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fmin.S
@@ -0,0 +1,44 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+   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>
+
+	.text
+ENTRY(__fmin)
+	fldl	4(%esp)		// x
+	fldl	12(%esp)	// x : y
+
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	1f		// y == NaN
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jc	2f
+
+1:	fxch	%st(1)
+2:	fstp	%st(1)
+
+	ret
+END(__fmin)
+weak_alias (__fmin, fmin)
diff --git a/sysdeps/i386/fpu/s_fminf.S b/sysdeps/i386/fpu/s_fminf.S
new file mode 100644
index 0000000000..7dd346d2bc
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fminf.S
@@ -0,0 +1,44 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+   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>
+
+	.text
+ENTRY(__fminf)
+	flds	4(%esp)		// x
+	flds	8(%esp)		// x : y
+
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	1f		// y == NaN
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jc	2f
+
+1:	fxch	%st(1)
+2:	fstp	%st(1)
+
+	ret
+END(__fminf)
+weak_alias (__fminf, fminf)
diff --git a/sysdeps/i386/fpu/s_fminl.S b/sysdeps/i386/fpu/s_fminl.S
new file mode 100644
index 0000000000..883735d32c
--- /dev/null
+++ b/sysdeps/i386/fpu/s_fminl.S
@@ -0,0 +1,44 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+   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>
+
+	.text
+ENTRY(__fminl)
+	fldt	4(%esp)		// x
+	fldt	16(%esp)	// x : y
+
+	fxam
+	fnstsw
+	andb	$0x45, %ah
+	cmpb	$0x01, %ah
+	je	1f		// y == NaN
+
+	fucom	%st(1)
+	fnstsw
+	sahf
+	jc	2f
+
+1:	fxch	%st(1)
+2:	fstp	%st(1)
+
+	ret
+END(__fminl)
+weak_alias (__fminl, fminl)
diff --git a/sysdeps/i386/fpu/s_frexp.S b/sysdeps/i386/fpu/s_frexp.S
new file mode 100644
index 0000000000..6a05f26720
--- /dev/null
+++ b/sysdeps/i386/fpu/s_frexp.S
@@ -0,0 +1,82 @@
+/* ix87 specific frexp implementation 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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(two54,@object)
+two54:	.byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
+	ASM_SIZE_DIRECTIVE(two54)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__frexp)
+	movl	4(%esp), %ecx
+	movl	8(%esp), %eax
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+	orl	%eax, %ecx
+	jz	1f
+	xorl	%ecx, %ecx
+	cmpl	$0x7ff00000, %eax
+	jae	1f
+
+	cmpl	$0x00100000, %eax
+	jae	2f
+
+	fldl	4(%esp)
+#ifdef	PIC
+	call	3f
+3:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
+#endif
+	fmull	MO(two54)
+	movl	$-54, %ecx
+	fstpl	4(%esp)
+	movl	8(%esp), %eax
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+
+2:	shrl	$20, %eax
+	andl	$0x800fffff, %edx
+	subl	$1022, %eax
+	orl	$0x3fe00000, %edx
+	addl	%eax, %ecx
+	movl	%edx, 8(%esp)
+
+	/* Store %ecx in the variable pointed to by the second argument,
+	   get the factor from the stack and return.  */
+1:	movl	12(%esp), %eax
+	fldl	4(%esp)
+	movl	%ecx, (%eax)
+	ret
+END(__frexp)
+weak_alias (__frexp, frexp)
diff --git a/sysdeps/i386/fpu/s_frexpf.S b/sysdeps/i386/fpu/s_frexpf.S
new file mode 100644
index 0000000000..1021b97aee
--- /dev/null
+++ b/sysdeps/i386/fpu/s_frexpf.S
@@ -0,0 +1,80 @@
+/* ix87 specific frexp implementation 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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(two25,@object)
+two25:	.byte 0, 0, 0, 0x4c
+	ASM_SIZE_DIRECTIVE(two25)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__frexpf)
+	movl	4(%esp), %eax
+	xorl	%ecx, %ecx
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+	jz	1f
+	cmpl	$0x7f800000, %eax
+	jae	1f
+
+	cmpl	$0x00800000, %eax
+	jae	2f
+
+	flds	4(%esp)
+#ifdef	PIC
+	call	3f
+3:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
+#endif
+	fmuls	MO(two25)
+	movl	$-25, %ecx
+	fstps	4(%esp)
+	movl	4(%esp), %eax
+	movl	%eax, %edx
+	andl	$0x7fffffff, %eax
+
+2:	shrl	$23, %eax
+	andl	$0x807fffff, %edx
+	subl	$126, %eax
+	orl	$0x3f000000, %edx
+	addl	%eax, %ecx
+	movl	%edx, 4(%esp)
+
+	/* Store %ecx in the variable pointed to by the second argument,
+	   get the factor from the stack and return.  */
+1:	movl	8(%esp), %eax
+	flds	4(%esp)
+	movl	%ecx, (%eax)
+	ret
+END(__frexpf)
+weak_alias (__frexpf, frexpf)
diff --git a/sysdeps/i386/fpu/s_frexpl.S b/sysdeps/i386/fpu/s_frexpl.S
new file mode 100644
index 0000000000..e3019ced6d
--- /dev/null
+++ b/sysdeps/i386/fpu/s_frexpl.S
@@ -0,0 +1,82 @@
+/* ix87 specific frexp implementation 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 <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(two64,@object)
+two64:	.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
+	ASM_SIZE_DIRECTIVE(two64)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__frexpl)
+	movl	4(%esp), %ecx
+	movl	12(%esp), %eax
+	orl	8(%esp), %ecx
+	movl	%eax, %edx
+	andl	$0x7fff, %eax
+	orl	%eax, %ecx
+	jz	1f
+	xorl	%ecx, %ecx
+	cmpl	$0x7fff, %eax
+	je	1f
+
+	cmpl	$0, %eax
+	je	2f
+
+	fldt	4(%esp)
+#ifdef	PIC
+	call	3f
+3:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
+#endif
+	fmull	MO(two64)	/* It's not necessary to use a 80bit factor */
+	movl	$-64, %ecx
+	fstpt	4(%esp)
+	movl	12(%esp), %eax
+	movl	%eax, %edx
+	andl	$0x7fff, %eax
+
+2:	andl	$0x8000, %edx
+	subl	$16382, %eax
+	orl	$0x3ffe, %edx
+	addl	%eax, %ecx
+	movl	%edx, 12(%esp)
+
+	/* Store %ecx in the variable pointed to by the second argument,
+	   get the factor from the stack and return.  */
+1:	movl	16(%esp), %eax
+	fldt	4(%esp)
+	movl	%ecx, (%eax)
+	ret
+END(__frexpl)
+weak_alias (__frexpl, frexpl)
diff --git a/sysdeps/i386/fpu/s_ilogb.S b/sysdeps/i386/fpu/s_ilogb.S
new file mode 100644
index 0000000000..36fb000c02
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ilogb.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/12 15:53:09 jtc Exp $")
+
+ENTRY(__ilogb)
+	fldl	4(%esp)
+	fxtract
+	pushl	%eax
+	fstp	%st
+
+	fistpl	(%esp)
+	fwait
+	popl	%eax
+
+	ret
+END (__ilogb)
+weak_alias (__ilogb, ilogb)
diff --git a/sysdeps/i386/fpu/s_ilogbf.S b/sysdeps/i386/fpu/s_ilogbf.S
new file mode 100644
index 0000000000..54f9d4647e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ilogbf.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10/22 20:32:43 pk Exp $")
+
+ENTRY(__ilogbf)
+	flds	4(%esp)
+	fxtract
+	pushl	%eax
+	fstp	%st
+
+	fistpl	(%esp)
+	fwait
+	popl	%eax
+
+	ret
+END (__ilogbf)
+weak_alias (__ilogbf, ilogbf)
diff --git a/sysdeps/i386/fpu/s_ilogbl.S b/sysdeps/i386/fpu/s_ilogbl.S
new file mode 100644
index 0000000000..1dad93abeb
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ilogbl.S
@@ -0,0 +1,23 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ilogbl)
+	fldt	4(%esp)
+	fxtract
+	pushl	%eax
+	fstp	%st
+
+	fistpl	(%esp)
+	fwait
+	popl	%eax
+
+	ret
+END (__ilogbl)
+weak_alias (__ilogbl, ilogbl)
diff --git a/sysdeps/i386/fpu/s_isinfl.c b/sysdeps/i386/fpu/s_isinfl.c
new file mode 100644
index 0000000000..f07898fd1b
--- /dev/null
+++ b/sysdeps/i386/fpu/s_isinfl.c
@@ -0,0 +1,36 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Change for long double by Ulrich Drepper <drepper@cygnus.com>.
+ * Intel i387 specific version.
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/*
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+	int __isinfl(long double x)
+#else
+	int __isinfl(x)
+	long double x;
+#endif
+{
+	int32_t se,hx,lx;
+	GET_LDOUBLE_WORDS(se,hx,lx,x);
+	/* This additional ^ 0x80000000 is necessary because in Intel's
+	   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/i386/fpu/s_isnanl.c b/sysdeps/i386/fpu/s_isnanl.c
new file mode 100644
index 0000000000..6a74b956cc
--- /dev/null
+++ b/sysdeps/i386/fpu/s_isnanl.c
@@ -0,0 +1,47 @@
+/* s_isnanl.c -- long double version for i387 of s_isnan.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
+
+/*
+ * isnanl(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+	int __isnanl(long double x)
+#else
+	int __isnanl(x)
+	long double x;
+#endif
+{
+	int32_t se,hx,lx;
+	GET_LDOUBLE_WORDS(se,hx,lx,x);
+	se = (se & 0x7fff) << 1;
+	/* The additional & 0x7fffffff is required because Intel's
+	   extended format has the normally implicit 1 explicit
+	   present.  Sigh!  */
+	lx |= hx & 0x7fffffff;
+	se |= (u_int32_t)(lx|(-lx))>>31;
+	se = 0xfffe - se;
+	return (int)((u_int32_t)(se))>>16;
+}
+weak_alias (__isnanl, isnanl)
diff --git a/sysdeps/i386/fpu/s_llrint.S b/sysdeps/i386/fpu/s_llrint.S
new file mode 100644
index 0000000000..6109ec45c3
--- /dev/null
+++ b/sysdeps/i386/fpu/s_llrint.S
@@ -0,0 +1,34 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.
+   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>
+
+	.text
+ENTRY(__llrint)
+	fldl	4(%esp)
+	subl	$8, %esp
+	fistpll	(%esp)
+	fwait
+	popl	%eax
+	popl	%edx
+	ret
+END(__llrint)
+weak_alias (__llrint, llrint)
diff --git a/sysdeps/i386/fpu/s_llrintf.S b/sysdeps/i386/fpu/s_llrintf.S
new file mode 100644
index 0000000000..c1e1c225c0
--- /dev/null
+++ b/sysdeps/i386/fpu/s_llrintf.S
@@ -0,0 +1,34 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.
+   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>
+
+	.text
+ENTRY(__llrintf)
+	flds	4(%esp)
+	subl	$8, %esp
+	fistpll	(%esp)
+	fwait
+	popl	%eax
+	popl	%edx
+	ret
+END(__llrintf)
+weak_alias (__llrintf, llrintf)
diff --git a/sysdeps/i386/fpu/s_llrintl.S b/sysdeps/i386/fpu/s_llrintl.S
new file mode 100644
index 0000000000..d894897d5e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_llrintl.S
@@ -0,0 +1,34 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.
+   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>
+
+	.text
+ENTRY(__llrintl)
+	fldt	4(%esp)
+	subl	$8, %esp
+	fistpll	(%esp)
+	fwait
+	popl	%eax
+	popl	%edx
+	ret
+END(__llrintl)
+weak_alias (__llrintl, llrintl)
diff --git a/sysdeps/i386/fpu/s_log1p.S b/sysdeps/i386/fpu/s_log1p.S
new file mode 100644
index 0000000000..10e8a36369
--- /dev/null
+++ b/sysdeps/i386/fpu/s_log1p.S
@@ -0,0 +1,62 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	/* The fyl2xp1 can only be used for values in
+		-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+	   0.29 is a safe value.
+	*/
+limit:	.double 0.29
+one:	.double 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+	.text
+ENTRY(__log1p)
+	fldln2
+
+	fldl	4(%esp)
+
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+	fld	%st
+	fabs
+#ifdef PIC
+	fcompl	limit@GOTOFF(%edx)
+#else
+	fcompl	limit
+#endif
+	fnstsw
+	sahf
+	jc	2f
+
+#ifdef PIC
+	faddl	one@GOTOFF(%edx)
+#else
+	faddl	one
+#endif
+	fyl2x
+	ret
+
+2:	fyl2xp1
+	ret
+
+END (__log1p)
+weak_alias (__log1p, log1p)
diff --git a/sysdeps/i386/fpu/s_log1pf.S b/sysdeps/i386/fpu/s_log1pf.S
new file mode 100644
index 0000000000..df9fdcbcfc
--- /dev/null
+++ b/sysdeps/i386/fpu/s_log1pf.S
@@ -0,0 +1,62 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1pf.S,v 1.4 1995/05/09 00:13:05 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	/* The fyl2xp1 can only be used for values in
+		-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+	   0.29 is a safe value.
+	*/
+limit:	.float 0.29
+one:	.float 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+	.text
+ENTRY(__log1pf)
+	fldln2
+
+	flds	4(%esp)
+
+#ifdef	PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+	fld	%st
+	fabs
+#ifdef PIC
+	fcomps	limit@GOTOFF(%edx)
+#else
+	fcomps	limit
+#endif
+	fnstsw
+	sahf
+	jc	2f
+
+#ifdef PIC
+	fadds	one@GOTOFF(%edx)
+#else
+	fadds	one
+#endif
+	fyl2x
+	ret
+
+2:	fyl2xp1
+	ret
+
+END (__log1pf)
+weak_alias (__log1pf, log1pf)
diff --git a/sysdeps/i386/fpu/s_log1pl.S b/sysdeps/i386/fpu/s_log1pl.S
new file mode 100644
index 0000000000..05a17b2831
--- /dev/null
+++ b/sysdeps/i386/fpu/s_log1pl.S
@@ -0,0 +1,68 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	/* The fyl2xp1 can only be used for values in
+		-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+	   0.29 is a safe value.
+	*/
+limit:	.tfloat 0.29
+	/* Please note:	 we use a double value here.  Since 1.0 has
+	   an exact representation this does not effect the accuracy
+	   but it helps to optimize the code.  */
+one:	.double 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+	.text
+ENTRY(__log1pl)
+	fldln2
+
+	fldt	4(%esp)
+
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+	fld	%st
+	fabs
+#ifdef PIC
+	fldt	limit@GOTOFF(%edx)
+#else
+	fldt	limit
+#endif
+	fcompp
+	fnstsw
+	sahf
+	jnc	2f
+
+#ifdef PIC
+	faddl	one@GOTOFF(%edx)
+#else
+	faddl	one
+#endif
+	fyl2x
+	ret
+
+2:	fyl2xp1
+	ret
+
+END (__log1pl)
+weak_alias (__log1pl, log1pl)
diff --git a/sysdeps/i386/fpu/s_log2.S b/sysdeps/i386/fpu/s_log2.S
new file mode 100644
index 0000000000..4632c96f67
--- /dev/null
+++ b/sysdeps/i386/fpu/s_log2.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__log2)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fldl	MO(one)
+	fldl	4(%esp)		// x : 1
+	fld	%st		// x : x : 1
+	fsub	%st(2), %st	// x-1 : x : 1
+	fld	%st		// x-1 : x-1 : x : 1
+	fabs			// |x-1| : x-1 : x : 1
+	fcompl	MO(limit)	// x-1 : x : 1
+	fnstsw			// x-1 : x : 1
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : 1
+	fyl2xp1			// log(x)
+	ret
+
+2:	fstp	%st(0)		// x : 1
+	fyl2x			// log(x)
+	ret
+END (__log2)
+weak_alias (__log2, log2)
diff --git a/sysdeps/i386/fpu/s_log2f.S b/sysdeps/i386/fpu/s_log2f.S
new file mode 100644
index 0000000000..bfdd0ef88e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_log2f.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__log2f)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fldl	MO(one)
+	flds	4(%esp)		// x : 1
+	fld	%st		// x : x : 1
+	fsub	%st(2), %st	// x-1 : x : 1
+	fld	%st		// x-1 : x-1 : x : 1
+	fabs			// |x-1| : x-1 : x : 1
+	fcompl	MO(limit)	// x-1 : x : 1
+	fnstsw			// x-1 : x : 1
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : 1
+	fyl2xp1			// log(x)
+	ret
+
+2:	fstp	%st(0)		// x : 1
+	fyl2x			// log(x)
+	ret
+END (__log2f)
+weak_alias (__log2f, log2f)
diff --git a/sysdeps/i386/fpu/s_log2l.S b/sysdeps/i386/fpu/s_log2l.S
new file mode 100644
index 0000000000..184981c4bb
--- /dev/null
+++ b/sysdeps/i386/fpu/s_log2l.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+	.section .rodata
+#else
+	.text
+#endif
+	.align ALIGNARG(4)
+	ASM_TYPE_DIRECTIVE(one,@object)
+one:	.double 1.0
+	ASM_SIZE_DIRECTIVE(one)
+	/* It is not important that this constant is precise.  It is only
+	   a value which is known to be on the safe side for using the
+	   fyl2xp1 instruction.  */
+	ASM_TYPE_DIRECTIVE(limit,@object)
+limit:	.double 0.29
+	ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+	.text
+ENTRY(__log2l)
+#ifdef PIC
+	call	1f
+1:	popl	%edx
+	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+	fldl	MO(one)
+	fldt	4(%esp)		// x : 1
+	fld	%st		// x : x : 1
+	fsub	%st(2), %st	// x-1 : x : 1
+	fld	%st		// x-1 : x-1 : x : 1
+	fabs			// |x-1| : x-1 : x : 1
+	fcompl	MO(limit)	// x-1 : x : 1
+	fnstsw			// x-1 : x : 1
+	andb	$0x45, %ah
+	jz	2f
+	fstp	%st(1)		// x-1 : 1
+	fyl2xp1			// log(x)
+	ret
+
+2:	fstp	%st(0)		// x : 1
+	fyl2x			// log(x)
+	ret
+END (__log2l)
+weak_alias (__log2l, log2l)
diff --git a/sysdeps/i386/fpu/s_logb.S b/sysdeps/i386/fpu/s_logb.S
new file mode 100644
index 0000000000..f78c091c8a
--- /dev/null
+++ b/sysdeps/i386/fpu/s_logb.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_logb.S,v 1.4 1995/05/09 00:14:30 jtc Exp $")
+
+ENTRY(__logb)
+	fldl	4(%esp)
+	fxtract
+	fstp	%st
+	ret
+END (__logb)
+weak_alias (__logb, logb)
diff --git a/sysdeps/i386/fpu/s_logbf.S b/sysdeps/i386/fpu/s_logbf.S
new file mode 100644
index 0000000000..91eb3d2925
--- /dev/null
+++ b/sysdeps/i386/fpu/s_logbf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_logbf.S,v 1.3 1995/05/09 00:15:12 jtc Exp $")
+
+ENTRY(__logbf)
+	flds	4(%esp)
+	fxtract
+	fstp	%st
+	ret
+END (__logbf)
+weak_alias (__logbf, logbf)
diff --git a/sysdeps/i386/fpu/s_logbl.S b/sysdeps/i386/fpu/s_logbl.S
new file mode 100644
index 0000000000..5c9a9c1c9d
--- /dev/null
+++ b/sysdeps/i386/fpu/s_logbl.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__logbl)
+	fldt	4(%esp)
+	fxtract
+	fstp	%st
+	ret
+END (__logbl)
+weak_alias (__logbl, logbl)
diff --git a/sysdeps/i386/fpu/s_lrint.S b/sysdeps/i386/fpu/s_lrint.S
new file mode 100644
index 0000000000..40956ab0d0
--- /dev/null
+++ b/sysdeps/i386/fpu/s_lrint.S
@@ -0,0 +1,33 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.
+   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>
+
+	.text
+ENTRY(__lrint)
+	fldl	4(%esp)
+	subl	$4, %esp
+	fistpl	(%esp)
+	fwait
+	popl	%eax
+	ret
+END(__lrint)
+weak_alias (__lrint, lrint)
diff --git a/sysdeps/i386/fpu/s_lrintf.S b/sysdeps/i386/fpu/s_lrintf.S
new file mode 100644
index 0000000000..2f49bdbabe
--- /dev/null
+++ b/sysdeps/i386/fpu/s_lrintf.S
@@ -0,0 +1,33 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.
+   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>
+
+	.text
+ENTRY(__lrintf)
+	flds	4(%esp)
+	subl	$4, %esp
+	fistpl	(%esp)
+	fwait
+	popl	%eax
+	ret
+END(__lrintf)
+weak_alias (__lrintf, lrintf)
diff --git a/sysdeps/i386/fpu/s_lrintl.S b/sysdeps/i386/fpu/s_lrintl.S
new file mode 100644
index 0000000000..3a06c91b29
--- /dev/null
+++ b/sysdeps/i386/fpu/s_lrintl.S
@@ -0,0 +1,33 @@
+/* Round argument to nearest integral value according to current rounding
+   direction.
+   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>
+
+	.text
+ENTRY(__lrintl)
+	fldt	4(%esp)
+	subl	$4, %esp
+	fistpl	(%esp)
+	fwait
+	popl	%eax
+	ret
+END(__lrintl)
+weak_alias (__lrintl, lrintl)
diff --git a/sysdeps/i386/fpu/s_nearbyint.S b/sysdeps/i386/fpu/s_nearbyint.S
new file mode 100644
index 0000000000..65ce4f76a1
--- /dev/null
+++ b/sysdeps/i386/fpu/s_nearbyint.S
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.  */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyint)
+	fldl	4(%esp)
+	pushl	%eax
+	pushl	%ecx
+	fnstcw	(%esp)
+	movl	(%esp), %eax
+	andl	$~0x20, %eax
+	movl	%eax, 4(%esp)
+	fldcw	4(%esp)
+	frndint
+	fclex
+	fldcw	(%esp)
+	popl	%ecx
+	popl	%eax
+	ret
+END (__nearbyint)
+weak_alias (__nearbyint, nearbyint)
diff --git a/sysdeps/i386/fpu/s_nearbyintf.S b/sysdeps/i386/fpu/s_nearbyintf.S
new file mode 100644
index 0000000000..090c631607
--- /dev/null
+++ b/sysdeps/i386/fpu/s_nearbyintf.S
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.  */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyintf)
+	flds	4(%esp)
+	pushl	%eax
+	pushl	%ecx
+	fnstcw	(%esp)
+	movl	(%esp), %eax
+	andl	$~0x20, %eax
+	movl	%eax, 4(%esp)
+	fldcw	4(%esp)
+	frndint
+	fclex
+	fldcw	(%esp)
+	popl	%ecx
+	popl	%eax
+	ret
+END (__nearbyintf)
+weak_alias (__nearbyintf, nearbyintf)
diff --git a/sysdeps/i386/fpu/s_nearbyintl.S b/sysdeps/i386/fpu/s_nearbyintl.S
new file mode 100644
index 0000000000..2f60af8f18
--- /dev/null
+++ b/sysdeps/i386/fpu/s_nearbyintl.S
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.  */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyintl)
+	fldt	4(%esp)
+	pushl	%eax
+	pushl	%ecx
+	fnstcw	(%esp)
+	movl	(%esp), %eax
+	andl	$~0x20, %eax
+	movl	%eax, 4(%esp)
+	fldcw	4(%esp)
+	frndint
+	fclex
+	fldcw	(%esp)
+	popl	%ecx
+	popl	%eax
+	ret
+END (__nearbyintl)
+weak_alias (__nearbyintl, nearbyintl)
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
new file mode 100644
index 0000000000..4596c6b93c
--- /dev/null
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -0,0 +1,102 @@
+/* s_nextafterl.c -- long double version of s_nextafter.c.
+ * Special version for i387.
+ * 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
+
+/* IEEE functions
+ *	nextafterl(x,y)
+ *	return the next machine floating-point number of x in the
+ *	direction toward y.
+ *   Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+	long double __nextafterl(long double x, long double y)
+#else
+	long double __nextafterl(x,y)
+	long double x,y;
+#endif
+{
+	int32_t hx,hy,ix,iy;
+	u_int32_t lx,ly,esx,esy;
+
+	GET_LDOUBLE_WORDS(esx,hx,lx,x);
+	GET_LDOUBLE_WORDS(esy,hy,ly,y);
+	ix = esx&0x7fff;		/* |x| */
+	iy = esy&0x7fff;		/* |y| */
+
+	/* The additional &hx/&hy is required because Intel's extended format
+           has the normally implicit 1 explicit present.  Sigh!  */
+	if(((ix==0x7fff)&&(((hx|lx)|-(hx|lx))&hx)>>31!=0) ||   /* x is nan */
+	   ((iy==0x7fff)&&(((hy|ly)|-(hy|ly))&hy)>>31!=0))     /* y is nan */
+	   return x+y;
+	if(x==y) return y;		/* x=y, return y */
+	if((ix|hx|lx)==0) {			/* x == 0 */
+	    SET_LDOUBLE_WORDS(x,esx&0x8000,0,1);/* return +-minsubnormal */
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
+	}
+	if(esx<0x8000) {			/* x > 0 */
+	    if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
+	      /* x > y, x -= ulp */
+		if(lx==0) {
+		    if (hx==0) esx -= 1;
+		    hx -= 1;
+		}
+		lx -= 1;
+	    } else {				/* x < y, x += ulp */
+		lx += 1;
+		if(lx==0) {
+		    hx += 1;
+		    if (hx==0)
+			esx += 1;
+		}
+	    }
+	} else {				/* x < 0 */
+	    if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
+	      /* x < y, x -= ulp */
+		if(lx==0) {
+		    if (hx==0) esx -= 1;
+		    hx -= 1;
+		}
+		lx -= 1;
+	    } else {				/* x > y, x += ulp */
+		lx += 1;
+		if(lx==0) {
+		    hx += 1;
+		    if (hx==0) esx += 1;
+		}
+	    }
+	}
+	esy = esx&0x7fff;
+	if(esy==0x7fff) return x+x;	/* overflow  */
+	if(esy==0) {			/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+	        SET_LDOUBLE_WORDS(y,esx,hx,lx);
+		return y;
+	    }
+	}
+	SET_LDOUBLE_WORDS(x,esx,hx,lx);
+	return x;
+}
+weak_alias (__nextafterl, nextafterl)
diff --git a/sysdeps/i386/fpu/s_remquo.S b/sysdeps/i386/fpu/s_remquo.S
new file mode 100644
index 0000000000..8ada191771
--- /dev/null
+++ b/sysdeps/i386/fpu/s_remquo.S
@@ -0,0 +1,36 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__remquo)
+	fldl	12(%esp)
+	fldl	4(%esp)
+1:	fprem1
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	/* Compute the congruent of the quotient.  */
+	movl	%eax, %ecx
+	shrl	$8, %eax
+	shrl	$12, %ecx
+	andl	$4, %ecx
+	andl	$3, %eax
+	orl	%eax, %ecx
+	movl	$0xef2960, %eax
+	shrl	%cl, %eax
+	andl	$3, %eax
+	movl	20(%esp), %ecx
+	movl	8(%esp), %edx
+	xorl	16(%esp), %edx
+	testl	$0x80000000, %edx
+	jz	1f
+	negl	%eax
+1:	movl	%eax, (%ecx)
+	ret
+END (__remquo)
+weak_alias (__remquo, remquo)
diff --git a/sysdeps/i386/fpu/s_remquof.S b/sysdeps/i386/fpu/s_remquof.S
new file mode 100644
index 0000000000..f60aec9c46
--- /dev/null
+++ b/sysdeps/i386/fpu/s_remquof.S
@@ -0,0 +1,36 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__remquof)
+	flds	8(%esp)
+	flds	4(%esp)
+1:	fprem1
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	/* Compute the congruent of the quotient.  */
+	movl	%eax, %ecx
+	shrl	$8, %eax
+	shrl	$12, %ecx
+	andl	$4, %ecx
+	andl	$3, %eax
+	orl	%eax, %ecx
+	movl	$0xef2960, %eax
+	shrl	%cl, %eax
+	andl	$3, %eax
+	movl	12(%esp), %ecx
+	movl	4(%esp), %edx
+	xorl	8(%esp), %edx
+	testl	$0x80000000, %edx
+	jz	1f
+	negl	%eax
+1:	movl	%eax, (%ecx)
+	ret
+END (__remquof)
+weak_alias (__remquof, remquof)
diff --git a/sysdeps/i386/fpu/s_remquol.S b/sysdeps/i386/fpu/s_remquol.S
new file mode 100644
index 0000000000..115d6e874b
--- /dev/null
+++ b/sysdeps/i386/fpu/s_remquol.S
@@ -0,0 +1,36 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__remquol)
+	fldt	16(%esp)
+	fldt	4(%esp)
+1:	fprem1
+	fstsw	%ax
+	sahf
+	jp	1b
+	fstp	%st(1)
+	/* Compute the congruent of the quotient.  */
+	movl	%eax, %ecx
+	shrl	$8, %eax
+	shrl	$12, %ecx
+	andl	$4, %ecx
+	andl	$3, %eax
+	orl	%eax, %ecx
+	movl	$0xef2960, %eax
+	shrl	%cl, %eax
+	andl	$3, %eax
+	movl	28(%esp), %ecx
+	movl	12(%esp), %edx
+	xorl	24(%esp), %edx
+	testl	$0x8000, %edx
+	jz	1f
+	negl	%eax
+1:	movl	%eax, (%ecx)
+	ret
+END (__remquol)
+weak_alias (__remquol, remquol)
diff --git a/sysdeps/i386/fpu/s_rint.S b/sysdeps/i386/fpu/s_rint.S
new file mode 100644
index 0000000000..be36c5f0ca
--- /dev/null
+++ b/sysdeps/i386/fpu/s_rint.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_rint.S,v 1.4 1995/05/09 00:16:08 jtc Exp $")
+
+ENTRY(__rint)
+	fldl	4(%esp)
+	frndint
+	ret
+END (__rint)
+weak_alias (__rint, rint)
diff --git a/sysdeps/i386/fpu/s_rintf.S b/sysdeps/i386/fpu/s_rintf.S
new file mode 100644
index 0000000000..2b358c1cf1
--- /dev/null
+++ b/sysdeps/i386/fpu/s_rintf.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_rintf.S,v 1.3 1995/05/09 00:17:22 jtc Exp $")
+
+ENTRY(__rintf)
+	flds	4(%esp)
+	frndint
+	ret
+END (__rintf)
+weak_alias (__rintf, rintf)
diff --git a/sysdeps/i386/fpu/s_rintl.S b/sysdeps/i386/fpu/s_rintl.S
new file mode 100644
index 0000000000..fd1ae6324e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_rintl.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__rintl)
+	fldt	4(%esp)
+	frndint
+	ret
+END (__rintl)
+weak_alias (__rintl, rintl)
diff --git a/sysdeps/i386/fpu/s_scalbln.c b/sysdeps/i386/fpu/s_scalbln.c
new file mode 100644
index 0000000000..1009713fbc
--- /dev/null
+++ b/sysdeps/i386/fpu/s_scalbln.c
@@ -0,0 +1,2 @@
+/* Nothing to do.  This function is the same as scalbn.  So we define an
+   alias.  */
diff --git a/sysdeps/i386/fpu/s_scalblnf.c b/sysdeps/i386/fpu/s_scalblnf.c
new file mode 100644
index 0000000000..5e558c3540
--- /dev/null
+++ b/sysdeps/i386/fpu/s_scalblnf.c
@@ -0,0 +1,2 @@
+/* Nothing to do.  This function is the same as scalbnf.  So we define an
+   alias.  */
diff --git a/sysdeps/i386/fpu/s_scalblnl.c b/sysdeps/i386/fpu/s_scalblnl.c
new file mode 100644
index 0000000000..cda2ec11c8
--- /dev/null
+++ b/sysdeps/i386/fpu/s_scalblnl.c
@@ -0,0 +1,2 @@
+/* Nothing to do.  This function is the same as scalbnl.  So we define an
+   alias.  */
diff --git a/sysdeps/i386/fpu/s_scalbn.S b/sysdeps/i386/fpu/s_scalbn.S
new file mode 100644
index 0000000000..ea9e25f094
--- /dev/null
+++ b/sysdeps/i386/fpu/s_scalbn.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_scalbn.S,v 1.4 1995/05/09 00:19:06 jtc Exp $")
+
+ENTRY(__scalbn)
+	fildl	12(%esp)
+	fldl	4(%esp)
+	fscale
+	fstp	%st(1)
+	ret
+END (__scalbn)
+weak_alias (__scalbn, scalbn)
+strong_alias (__scalbn, __scalbln)
+weak_alias (__scalbn, scalbln)
diff --git a/sysdeps/i386/fpu/s_scalbnf.S b/sysdeps/i386/fpu/s_scalbnf.S
new file mode 100644
index 0000000000..dc8cfb4296
--- /dev/null
+++ b/sysdeps/i386/fpu/s_scalbnf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_scalbnf.S,v 1.3 1995/05/09 00:19:59 jtc Exp $")
+
+ENTRY(__scalbnf)
+	fildl	8(%esp)
+	flds	4(%esp)
+	fscale
+	fstp	%st(1)
+	ret
+END (__scalbnf)
+weak_alias (__scalbnf, scalbnf)
+strong_alias (__scalbnf, __scalblnf)
+weak_alias (__scalbnf, scalblnf)
diff --git a/sysdeps/i386/fpu/s_scalbnl.S b/sysdeps/i386/fpu/s_scalbnl.S
new file mode 100644
index 0000000000..295494b3d2
--- /dev/null
+++ b/sysdeps/i386/fpu/s_scalbnl.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__scalbnl)
+	fildl	16(%esp)
+	fldt	4(%esp)
+	fscale
+	fstp	%st(1)
+	ret
+END (__scalbnl)
+weak_alias (__scalbnl, scalbnl)
+strong_alias (__scalbnl, __scalblnl)
+weak_alias (__scalbnl, scalblnl)
diff --git a/sysdeps/i386/fpu/s_significand.S b/sysdeps/i386/fpu/s_significand.S
new file mode 100644
index 0000000000..4859b7ed71
--- /dev/null
+++ b/sysdeps/i386/fpu/s_significand.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_significand.S,v 1.4 1995/05/09 00:21:47 jtc Exp $")
+
+ENTRY(__significand)
+	fldl	4(%esp)
+	fxtract
+	fstp	%st(1)
+	ret
+END (__significand)
+weak_alias (__significand, significand)
diff --git a/sysdeps/i386/fpu/s_significandf.S b/sysdeps/i386/fpu/s_significandf.S
new file mode 100644
index 0000000000..3a2de97759
--- /dev/null
+++ b/sysdeps/i386/fpu/s_significandf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_significandf.S,v 1.3 1995/05/09 00:24:07 jtc Exp $")
+
+ENTRY(__significandf)
+	flds	4(%esp)
+	fxtract
+	fstp	%st(1)
+	ret
+END (__significandf)
+weak_alias (__significandf, significandf)
diff --git a/sysdeps/i386/fpu/s_significandl.S b/sysdeps/i386/fpu/s_significandl.S
new file mode 100644
index 0000000000..e3a69cba73
--- /dev/null
+++ b/sysdeps/i386/fpu/s_significandl.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__significandl)
+	fldt	4(%esp)
+	fxtract
+	fstp	%st(0)
+	ret
+END (__significandl)
+weak_alias (__significandl, significandl)
diff --git a/sysdeps/i386/fpu/s_sin.S b/sysdeps/i386/fpu/s_sin.S
new file mode 100644
index 0000000000..eb22d7e98b
--- /dev/null
+++ b/sysdeps/i386/fpu/s_sin.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_sin.S,v 1.5 1995/05/09 00:25:54 jtc Exp $")
+
+ENTRY(__sin)
+	fldl	4(%esp)
+	fsin
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fsin
+	ret
+END (__sin)
+weak_alias (__sin, sin)
diff --git a/sysdeps/i386/fpu/s_sincos.S b/sysdeps/i386/fpu/s_sincos.S
new file mode 100644
index 0000000000..fe99f42d18
--- /dev/null
+++ b/sysdeps/i386/fpu/s_sincos.S
@@ -0,0 +1,48 @@
+/* Compute sine and cosine of argument.
+   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 <machine/asm.h>
+
+ENTRY(__sincos)
+	fldl	4(%esp)
+	fsincos
+	movl	12(%esp), %ecx
+	movl	16(%esp), %edx
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	fstpl	(%edx)
+	fstpl	(%ecx)
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fsincos
+	fstpl	(%edx)
+	fstpl	(%ecx)
+	ret
+END(__sincos)
+weak_alias(__sincos, sincos)
diff --git a/sysdeps/i386/fpu/s_sincosf.S b/sysdeps/i386/fpu/s_sincosf.S
new file mode 100644
index 0000000000..5bb13f3c33
--- /dev/null
+++ b/sysdeps/i386/fpu/s_sincosf.S
@@ -0,0 +1,48 @@
+/* Compute sine and cosine of argument.
+   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 <machine/asm.h>
+
+ENTRY(__sincosf)
+	flds	4(%esp)
+	fsincos
+	movl	8(%esp), %ecx
+	movl	12(%esp), %edx
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	fstps	(%edx)
+	fstps	(%ecx)
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fsincos
+	fstps	(%edx)
+	fstps	(%ecx)
+	ret
+END(__sincosf)
+weak_alias(__sincosf, sincosf)
diff --git a/sysdeps/i386/fpu/s_sincosl.S b/sysdeps/i386/fpu/s_sincosl.S
new file mode 100644
index 0000000000..8b6694f09f
--- /dev/null
+++ b/sysdeps/i386/fpu/s_sincosl.S
@@ -0,0 +1,48 @@
+/* Compute sine and cosine of argument.
+   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 <machine/asm.h>
+
+ENTRY(__sincosl)
+	fldt	4(%esp)
+	fsincos
+	movl	16(%esp), %ecx
+	movl	20(%esp), %edx
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	fstpt	(%edx)
+	fstpt	(%ecx)
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fsincos
+	fstpt	(%edx)
+	fstpt	(%ecx)
+	ret
+END(__sincosl)
+weak_alias(__sincosl, sincosl)
diff --git a/sysdeps/i386/fpu/s_sinf.S b/sysdeps/i386/fpu/s_sinf.S
new file mode 100644
index 0000000000..a010d60f5e
--- /dev/null
+++ b/sysdeps/i386/fpu/s_sinf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_sinf.S,v 1.3 1995/05/09 00:27:53 jtc Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(__sinf)
+	flds	4(%esp)
+	fsin
+	ret
+END (__sinf)
+weak_alias (__sinf, sinf)
diff --git a/sysdeps/i386/fpu/s_sinl.S b/sysdeps/i386/fpu/s_sinl.S
new file mode 100644
index 0000000000..3e215de5e1
--- /dev/null
+++ b/sysdeps/i386/fpu/s_sinl.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__sinl)
+	fldt	4(%esp)
+	fsin
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	ret
+	.align ALIGNARG(4)
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fsin
+	ret
+END (__sinl)
+weak_alias (__sinl, sinl)
diff --git a/sysdeps/i386/fpu/s_tan.S b/sysdeps/i386/fpu/s_tan.S
new file mode 100644
index 0000000000..7b3547af4c
--- /dev/null
+++ b/sysdeps/i386/fpu/s_tan.S
@@ -0,0 +1,30 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_tan.S,v 1.5 1995/05/09 00:30:00 jtc Exp $")
+
+ENTRY(__tan)
+	fldl	4(%esp)
+	fptan
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	fstp	%st(0)
+	ret
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fptan
+	fstp	%st(0)
+	ret
+END (__tan)
+weak_alias (__tan, tan)
diff --git a/sysdeps/i386/fpu/s_tanf.S b/sysdeps/i386/fpu/s_tanf.S
new file mode 100644
index 0000000000..7a7509119b
--- /dev/null
+++ b/sysdeps/i386/fpu/s_tanf.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_tanf.S,v 1.3 1995/05/09 00:31:09 jtc Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(__tanf)
+	flds	4(%esp)
+	fptan
+	fstp	%st(0)
+	ret
+END (__tanf)
+weak_alias (__tanf, tanf)
diff --git a/sysdeps/i386/fpu/s_tanl.S b/sysdeps/i386/fpu/s_tanl.S
new file mode 100644
index 0000000000..f2bdd6a605
--- /dev/null
+++ b/sysdeps/i386/fpu/s_tanl.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__tanl)
+	fldt	4(%esp)
+	fptan
+	fnstsw	%ax
+	testl	$0x400,%eax
+	jnz	1f
+	fstp	%st(0)
+	ret
+1:	fldpi
+	fadd	%st(0)
+	fxch	%st(1)
+2:	fprem1
+	fstsw	%ax
+	testl	$0x400,%eax
+	jnz	2b
+	fstp	%st(1)
+	fptan
+	fstp	%st(0)
+	ret
+END (__tanl)
+weak_alias (__tanl, tanl)
diff --git a/sysdeps/i386/fpu/s_trunc.S b/sysdeps/i386/fpu/s_trunc.S
new file mode 100644
index 0000000000..3100d716a9
--- /dev/null
+++ b/sysdeps/i386/fpu/s_trunc.S
@@ -0,0 +1,36 @@
+/* Truncate double 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.
+
+   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 <machine/asm.h>
+
+ENTRY(__trunc)
+	fldl	4(%esp)
+	subl	$8, %esp
+	fstcw	4(%esp)
+	movl	$0xc00, %edx
+	orl	4(%esp), %edx
+	movl	%edx, (%esp)
+	fldcw	(%esp)
+	frndint
+	fldcw	4(%esp)
+	addl	$8, %esp
+	ret
+END(__trunc)
+weak_alias (__trunc, trunc)
diff --git a/sysdeps/i386/fpu/s_truncf.S b/sysdeps/i386/fpu/s_truncf.S
new file mode 100644
index 0000000000..275e5f714c
--- /dev/null
+++ b/sysdeps/i386/fpu/s_truncf.S
@@ -0,0 +1,36 @@
+/* Truncate float 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.
+
+   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 <machine/asm.h>
+
+ENTRY(__truncf)
+	flds	4(%esp)
+	subl	$8, %esp
+	fstcw	4(%esp)
+	movl	$0xc00, %edx
+	orl	4(%esp), %edx
+	movl	%edx, (%esp)
+	fldcw	(%esp)
+	frndint
+	fldcw	4(%esp)
+	addl	$8, %esp
+	ret
+END(__truncf)
+weak_alias (__truncf, truncf)
diff --git a/sysdeps/i386/fpu/s_truncl.S b/sysdeps/i386/fpu/s_truncl.S
new file mode 100644
index 0000000000..4c0bb0ce53
--- /dev/null
+++ b/sysdeps/i386/fpu/s_truncl.S
@@ -0,0 +1,36 @@
+/* Truncate long double 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.
+
+   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 <machine/asm.h>
+
+ENTRY(__truncl)
+	fldt	4(%esp)
+	subl	$8, %esp
+	fstcw	4(%esp)
+	movl	$0xc00, %edx
+	orl	4(%esp), %edx
+	movl	%edx, (%esp)
+	fldcw	(%esp)
+	frndint
+	fldcw	4(%esp)
+	addl	$8, %esp
+	ret
+END(__truncl)
+weak_alias (__truncl, truncl)
diff --git a/sysdeps/i386/fpu/t_exp.c b/sysdeps/i386/fpu/t_exp.c
new file mode 100644
index 0000000000..fd37963b05
--- /dev/null
+++ b/sysdeps/i386/fpu/t_exp.c
@@ -0,0 +1 @@
+/* Empty.  Not needed. */