summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2004-02-08 18:03:51 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2004-02-08 18:03:51 +0000
commitf9d4dbafe850675850558e2c8597b232b8be0e88 (patch)
treec7db9cbea87fe13a78bd1aa5a591a820d663b9dc /lib
parentd1b83f8bb6e1bc54b2b16eace08563acb5e968a0 (diff)
add libm parts for amd64; much from netbsd, integration by mickey.
Instead of mixing the i387 & xmm register components, we decide to explicitly seperate them. libm is already confusing enough as it is, thank you very much
Diffstat (limited to 'lib')
-rw-r--r--lib/libm/Makefile12
-rw-r--r--lib/libm/arch/amd64/abi.h73
-rw-r--r--lib/libm/arch/amd64/e_acos.S24
-rw-r--r--lib/libm/arch/amd64/e_asin.S23
-rw-r--r--lib/libm/arch/amd64/e_atan2.S18
-rw-r--r--lib/libm/arch/amd64/e_atan2f.S18
-rw-r--r--lib/libm/arch/amd64/e_exp.S133
-rw-r--r--lib/libm/arch/amd64/e_fmod.S23
-rw-r--r--lib/libm/arch/amd64/e_log.S18
-rw-r--r--lib/libm/arch/amd64/e_log10.S18
-rw-r--r--lib/libm/arch/amd64/e_remainder.S22
-rw-r--r--lib/libm/arch/amd64/e_remainderf.S22
-rw-r--r--lib/libm/arch/amd64/e_scalb.S19
-rw-r--r--lib/libm/arch/amd64/e_sqrt.S17
-rw-r--r--lib/libm/arch/amd64/e_sqrtf.S17
-rw-r--r--lib/libm/arch/amd64/s_atan.S18
-rw-r--r--lib/libm/arch/amd64/s_atanf.S18
-rw-r--r--lib/libm/arch/amd64/s_ceil.S45
-rw-r--r--lib/libm/arch/amd64/s_ceilf.S43
-rw-r--r--lib/libm/arch/amd64/s_copysign.S53
-rw-r--r--lib/libm/arch/amd64/s_copysignf.S53
-rw-r--r--lib/libm/arch/amd64/s_cos.S31
-rw-r--r--lib/libm/arch/amd64/s_cosf.S18
-rw-r--r--lib/libm/arch/amd64/s_finite.S26
-rw-r--r--lib/libm/arch/amd64/s_finitef.S25
-rw-r--r--lib/libm/arch/amd64/s_floor.S43
-rw-r--r--lib/libm/arch/amd64/s_floorf.S43
-rw-r--r--lib/libm/arch/amd64/s_ilogb.S32
-rw-r--r--lib/libm/arch/amd64/s_ilogbf.S32
-rw-r--r--lib/libm/arch/amd64/s_log1p.S76
-rw-r--r--lib/libm/arch/amd64/s_log1pf.S76
-rw-r--r--lib/libm/arch/amd64/s_logb.S18
-rw-r--r--lib/libm/arch/amd64/s_logbf.S18
-rw-r--r--lib/libm/arch/amd64/s_rint.S17
-rw-r--r--lib/libm/arch/amd64/s_rintf.S17
-rw-r--r--lib/libm/arch/amd64/s_scalbn.S19
-rw-r--r--lib/libm/arch/amd64/s_scalbnf.S19
-rw-r--r--lib/libm/arch/amd64/s_significand.S18
-rw-r--r--lib/libm/arch/amd64/s_significandf.S18
-rw-r--r--lib/libm/arch/amd64/s_sin.S31
-rw-r--r--lib/libm/arch/amd64/s_sinf.S18
-rw-r--r--lib/libm/arch/amd64/s_tan.S33
-rw-r--r--lib/libm/arch/amd64/s_tanf.S19
-rw-r--r--lib/libm/arch/x86_64/abi.h73
-rw-r--r--lib/libm/arch/x86_64/e_acos.S24
-rw-r--r--lib/libm/arch/x86_64/e_asin.S23
-rw-r--r--lib/libm/arch/x86_64/e_atan2.S18
-rw-r--r--lib/libm/arch/x86_64/e_atan2f.S18
-rw-r--r--lib/libm/arch/x86_64/e_exp.S133
-rw-r--r--lib/libm/arch/x86_64/e_fmod.S23
-rw-r--r--lib/libm/arch/x86_64/e_log.S18
-rw-r--r--lib/libm/arch/x86_64/e_log10.S18
-rw-r--r--lib/libm/arch/x86_64/e_remainder.S22
-rw-r--r--lib/libm/arch/x86_64/e_remainderf.S22
-rw-r--r--lib/libm/arch/x86_64/e_scalb.S19
-rw-r--r--lib/libm/arch/x86_64/e_sqrt.S17
-rw-r--r--lib/libm/arch/x86_64/e_sqrtf.S17
-rw-r--r--lib/libm/arch/x86_64/s_atan.S18
-rw-r--r--lib/libm/arch/x86_64/s_atanf.S18
-rw-r--r--lib/libm/arch/x86_64/s_ceil.S45
-rw-r--r--lib/libm/arch/x86_64/s_ceilf.S43
-rw-r--r--lib/libm/arch/x86_64/s_copysign.S53
-rw-r--r--lib/libm/arch/x86_64/s_copysignf.S53
-rw-r--r--lib/libm/arch/x86_64/s_cos.S31
-rw-r--r--lib/libm/arch/x86_64/s_cosf.S18
-rw-r--r--lib/libm/arch/x86_64/s_finite.S26
-rw-r--r--lib/libm/arch/x86_64/s_finitef.S25
-rw-r--r--lib/libm/arch/x86_64/s_floor.S43
-rw-r--r--lib/libm/arch/x86_64/s_floorf.S43
-rw-r--r--lib/libm/arch/x86_64/s_ilogb.S32
-rw-r--r--lib/libm/arch/x86_64/s_ilogbf.S32
-rw-r--r--lib/libm/arch/x86_64/s_log1p.S76
-rw-r--r--lib/libm/arch/x86_64/s_log1pf.S76
-rw-r--r--lib/libm/arch/x86_64/s_logb.S18
-rw-r--r--lib/libm/arch/x86_64/s_logbf.S18
-rw-r--r--lib/libm/arch/x86_64/s_rint.S17
-rw-r--r--lib/libm/arch/x86_64/s_rintf.S17
-rw-r--r--lib/libm/arch/x86_64/s_scalbn.S19
-rw-r--r--lib/libm/arch/x86_64/s_scalbnf.S19
-rw-r--r--lib/libm/arch/x86_64/s_significand.S18
-rw-r--r--lib/libm/arch/x86_64/s_significandf.S18
-rw-r--r--lib/libm/arch/x86_64/s_sin.S31
-rw-r--r--lib/libm/arch/x86_64/s_sinf.S18
-rw-r--r--lib/libm/arch/x86_64/s_tan.S33
-rw-r--r--lib/libm/arch/x86_64/s_tanf.S19
85 files changed, 2655 insertions, 1 deletions
diff --git a/lib/libm/Makefile b/lib/libm/Makefile
index ff09ac83f61..758eb08eb4a 100644
--- a/lib/libm/Makefile
+++ b/lib/libm/Makefile
@@ -1,5 +1,5 @@
# $NetBSD: Makefile,v 1.28 1995/11/20 22:06:19 jtc Exp $
-# $OpenBSD: Makefile,v 1.30 2003/02/27 00:30:43 jason Exp $
+# $OpenBSD: Makefile,v 1.31 2004/02/08 18:03:48 deraadt Exp $
#
# @(#)Makefile 5.1beta 93/09/24
#
@@ -63,6 +63,16 @@ ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \
s_ilogb.S s_ilogbf.S s_log1p.S s_log1pf.S s_logb.S s_logbf.S \
s_rint.S s_rintf.S s_scalbn.S s_scalbnf.S s_significand.S \
s_significandf.S s_sin.S s_sinf.S s_tan.S s_tanf.S
+.elif (${MACHINE_ARCH} == "x86_64")
+.PATH: ${.CURDIR}/arch/x86_64
+CPPFLAGS+=-I${.CURDIR}/arch/x86_64
+ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \
+ e_remainder.S e_remainderf.S e_scalb.S e_sqrt.S e_sqrtf.S \
+ s_atan.S s_atanf.S s_ceil.S s_ceilf.S s_copysign.S s_copysignf.S \
+ s_cos.S s_cosf.S s_finite.S s_finitef.S s_floor.S s_floorf.S \
+ s_ilogb.S s_ilogbf.S s_log1p.S s_log1pf.S s_logb.S s_logbf.S \
+ s_rint.S s_rintf.S s_scalbn.S s_scalbnf.S s_significand.S \
+ s_significandf.S s_sin.S s_sinf.S s_tan.S s_tanf.S
.elif (${MACHINE_ARCH} == "m68k")
.PATH: ${.CURDIR}/arch/mc68881
ARCH_SRCS = e_acos.S e_asin.S e_atanh.S e_cosh.S e_exp.S e_log.S e_log10.S \
diff --git a/lib/libm/arch/amd64/abi.h b/lib/libm/arch/amd64/abi.h
new file mode 100644
index 00000000000..cbfbd02c5f5
--- /dev/null
+++ b/lib/libm/arch/amd64/abi.h
@@ -0,0 +1,73 @@
+/* $NetBSD: abi.h,v 1.2 2003/09/14 21:26:14 fvdl Exp $ */
+
+/*
+ * Written by Frank van der Linden (fvdl@wasabisystems.com)
+ */
+
+/*
+ * The x86-64 ABI specifies that float, double and long double
+ * arguments are passed in SSE2 (xmm) registers. Unfortunately,
+ * there is no way to push those on to the FP stack, which is
+ * where he fancier instructions get their arguments from.
+ *
+ * Define some prologues and epilogues to store and retrieve
+ * xmm regs to local variables.
+ */
+
+#ifdef __x86_64__
+
+#define ARG_DOUBLE_ONE -8(%rsp)
+#define ARG_DOUBLE_TWO -16(%rsp)
+#define ARG_FLOAT_ONE -4(%rsp)
+#define ARG_FLOAT_TWO -8(%rsp)
+
+#define XMM_ONE_ARG_DOUBLE_PROLOGUE \
+ movsd %xmm0, ARG_DOUBLE_ONE
+
+#define XMM_TWO_ARG_DOUBLE_PROLOGUE \
+ movsd %xmm0, ARG_DOUBLE_ONE ; \
+ movsd %xmm1, ARG_DOUBLE_TWO
+
+#define XMM_ONE_ARG_FLOAT_PROLOGUE \
+ movss %xmm0, ARG_FLOAT_ONE
+
+#define XMM_TWO_ARG_FLOAT_PROLOGUE \
+ movss %xmm0, ARG_FLOAT_ONE ; \
+ movss %xmm1, ARG_FLOAT_TWO
+
+#define XMM_DOUBLE_EPILOGUE \
+ fstpl ARG_DOUBLE_ONE ; \
+ movsd ARG_DOUBLE_ONE, %xmm0
+
+#define XMM_FLOAT_EPILOGUE \
+ fstps ARG_FLOAT_ONE ; \
+ movss ARG_FLOAT_ONE, %xmm0
+
+#define FLDL_VAR(x) fldl x(%rip)
+
+#else
+
+#define ARG_DOUBLE_ONE 4(%esp)
+#define ARG_DOUBLE_TWO 12(%esp)
+#define ARG_FLOAT_ONE 4(%esp)
+#define ARG_FLOAT_TWO 8(%esp)
+
+#define XMM_ONE_ARG_DOUBLE_PROLOGUE
+#define XMM_TWO_ARG_DOUBLE_PROLOGUE
+#define XMM_ONE_ARG_FLOAT_PROLOGUE
+#define XMM_TWO_ARG_FLOAT_PROLOGUE
+
+#define XMM_DOUBLE_EPILOGUE
+#define XMM_FLOAT_EPILOGUE
+
+#ifdef PIC
+#define FLDL_VAR(x) \
+ PIC_PROLOGUE ; \
+ fldl PIC_GOTOFF(x) ; \
+ PIC_EPILOGUE
+#else
+#define FLDL_VAR(x) \
+ fldl x
+
+#endif
+#endif
diff --git a/lib/libm/arch/amd64/e_acos.S b/lib/libm/arch/amd64/e_acos.S
new file mode 100644
index 00000000000..0c8f20e9a04
--- /dev/null
+++ b/lib/libm/arch/amd64/e_acos.S
@@ -0,0 +1,24 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_acos.S,v 1.8 2003/07/26 19:24:57 salo Exp $")
+
+/* acos = atan (sqrt(1 - x^2) / x) */
+ENTRY(__ieee754_acos)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE /* x */
+ fld %st(1)
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fxch %st(1)
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_asin.S b/lib/libm/arch/amd64/e_asin.S
new file mode 100644
index 00000000000..43bea55a236
--- /dev/null
+++ b/lib/libm/arch/amd64/e_asin.S
@@ -0,0 +1,23 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_asin.S,v 1.7 2003/07/26 19:24:58 salo Exp $")
+
+/* asin = atan (x / sqrt(1 - x^2)) */
+ENTRY(__ieee754_asin)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE /* x */
+ fld %st(0)
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_atan2.S b/lib/libm/arch/amd64/e_atan2.S
new file mode 100644
index 00000000000..d6d9fa24248
--- /dev/null
+++ b/lib/libm/arch/amd64/e_atan2.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_atan2.S,v 1.6 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_atan2)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fldl ARG_DOUBLE_TWO
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_atan2f.S b/lib/libm/arch/amd64/e_atan2f.S
new file mode 100644
index 00000000000..3aed1883532
--- /dev/null
+++ b/lib/libm/arch/amd64/e_atan2f.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_atan2f.S,v 1.3 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_atan2f)
+ XMM_TWO_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ flds ARG_FLOAT_TWO
+ fpatan
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_exp.S b/lib/libm/arch/amd64/e_exp.S
new file mode 100644
index 00000000000..cdbc7bd4800
--- /dev/null
+++ b/lib/libm/arch/amd64/e_exp.S
@@ -0,0 +1,133 @@
+/* $NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $ */
+
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $")
+#if 0
+RCSID("$FreeBSD: src/lib/msun/i387/e_exp.S,v 1.8.2.1 2000/07/10 09:16:28 obrien Exp $")
+#endif
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_exp)
+#ifndef __i386__
+ /*
+ * XXX: This code is broken and needs to be merged with the i386 case.
+ */
+ fstcw -12(%rsp)
+ movw -12(%rsp),%dx
+ orw $0x0180,%dx
+ movw %dx,-16(%rsp)
+ fldcw -16(%rsp)
+ movsd %xmm0,-8(%rsp)
+ fldl -8(%rsp)
+
+ fldl2e
+ fmulp /* x * log2(e) */
+ fld %st(0)
+ frndint /* int(x * log2(e)) */
+ fxch %st(1)
+ fsub %st(1),%st /* fract(x * log2(e)) */
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstp %st(1)
+
+ fstpl -8(%rsp)
+ movsd -8(%rsp),%xmm0
+ fldcw -12(%rsp)
+ ret
+#else
+ /*
+ * If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
+ * Avoid this. Also avoid it if x is NaN for convenience.
+ */
+ movl 8(%esp),%eax
+ andl $0x7fffffff,%eax
+ cmpl $0x7ff00000,%eax
+ jae x_Inf_or_NaN
+
+ fldl 4(%esp)
+
+ /*
+ * Ensure that the rounding mode is to nearest (to give the smallest
+ * possible fraction) and that the precision is as high as possible.
+ * We may as well mask interrupts if we switch the mode.
+ */
+ fstcw 4(%esp)
+ movl 4(%esp),%eax
+ andl $0x0300,%eax
+ cmpl $0x0300,%eax /* RC == 0 && PC == 3? */
+ je 1f /* jump if mode is good */
+ movl $0x137f,8(%esp)
+ fldcw 8(%esp)
+1:
+ fldl2e
+ fmulp /* x * log2(e) */
+ fst %st(1)
+ frndint /* int(x * log2(e)) */
+ fst %st(2)
+ fsubrp /* fract(x * log2(e)) */
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstp %st(1)
+ je 1f
+ fldcw 4(%esp)
+1:
+ ret
+
+x_Inf_or_NaN:
+ /*
+ * Return 0 if x is -Inf. Otherwise just return x, although the
+ * C version would return (x + x) (Real Indefinite) if x is a NaN.
+ */
+ cmpl $0xfff00000,8(%esp)
+ jne x_not_minus_Inf
+ cmpl $0,4(%esp)
+ jne x_not_minus_Inf
+ fldz
+ ret
+
+x_not_minus_Inf:
+ fldl 4(%esp)
+ ret
+#endif
diff --git a/lib/libm/arch/amd64/e_fmod.S b/lib/libm/arch/amd64/e_fmod.S
new file mode 100644
index 00000000000..4987f9e359c
--- /dev/null
+++ b/lib/libm/arch/amd64/e_fmod.S
@@ -0,0 +1,23 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+
+RCSID("$NetBSD: e_fmod.S,v 1.7 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_fmod)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+1: fprem
+ fstsw %ax
+ btw $10,%ax
+ jc 1b
+ fstp %st(1)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_log.S b/lib/libm/arch/amd64/e_log.S
new file mode 100644
index 00000000000..2d773255530
--- /dev/null
+++ b/lib/libm/arch/amd64/e_log.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_log.S,v 1.6 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_log)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldln2
+ fldl ARG_DOUBLE_ONE
+ fyl2x
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_log10.S b/lib/libm/arch/amd64/e_log10.S
new file mode 100644
index 00000000000..ce8e3b93a8e
--- /dev/null
+++ b/lib/libm/arch/amd64/e_log10.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_log10.S,v 1.6 2003/07/26 19:24:59 salo Exp $")
+
+ENTRY(__ieee754_log10)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldlg2
+ fldl ARG_DOUBLE_ONE
+ fyl2x
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_remainder.S b/lib/libm/arch/amd64/e_remainder.S
new file mode 100644
index 00000000000..70223b2ad79
--- /dev/null
+++ b/lib/libm/arch/amd64/e_remainder.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_remainder.S,v 1.7 2003/07/26 19:24:59 salo Exp $")
+
+ENTRY(__ieee754_remainder)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+1: fprem1
+ fstsw %ax
+ btw $10,%ax
+ jc 1b
+ fstp %st(1)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_remainderf.S b/lib/libm/arch/amd64/e_remainderf.S
new file mode 100644
index 00000000000..aaee4aab044
--- /dev/null
+++ b/lib/libm/arch/amd64/e_remainderf.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_remainderf.S,v 1.5 2003/07/26 19:24:59 salo Exp $")
+
+ENTRY(__ieee754_remainderf)
+ XMM_TWO_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_TWO
+ flds ARG_FLOAT_ONE
+1: fprem1
+ fstsw %ax
+ btw $10,%ax
+ jc 1b
+ fstp %st(1)
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_scalb.S b/lib/libm/arch/amd64/e_scalb.S
new file mode 100644
index 00000000000..8717aa7cb03
--- /dev/null
+++ b/lib/libm/arch/amd64/e_scalb.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_scalb.S,v 1.7 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(__ieee754_scalb)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+ fscale
+ fstp %st(1) /* bug fix for fp stack overflow */
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/e_sqrt.S b/lib/libm/arch/amd64/e_sqrt.S
new file mode 100644
index 00000000000..afae87ffc70
--- /dev/null
+++ b/lib/libm/arch/amd64/e_sqrt.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrt.S,v 1.6 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(__ieee754_sqrt)
+#ifdef __i386__
+ fldl 4(%esp)
+ fsqrt
+#else
+ sqrtsd %xmm0,%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/e_sqrtf.S b/lib/libm/arch/amd64/e_sqrtf.S
new file mode 100644
index 00000000000..f9163bab547
--- /dev/null
+++ b/lib/libm/arch/amd64/e_sqrtf.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrtf.S,v 1.4 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(__ieee754_sqrtf)
+#ifdef __i386__
+ flds 4(%esp)
+ fsqrt
+#else
+ sqrtss %xmm0,%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_atan.S b/lib/libm/arch/amd64/s_atan.S
new file mode 100644
index 00000000000..61a093309ec
--- /dev/null
+++ b/lib/libm/arch/amd64/s_atan.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_atan.S,v 1.6 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(atan)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fld1
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_atanf.S b/lib/libm/arch/amd64/s_atanf.S
new file mode 100644
index 00000000000..6eec1944ccf
--- /dev/null
+++ b/lib/libm/arch/amd64/s_atanf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_atanf.S,v 1.5 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(atanf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fld1
+ fpatan
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_ceil.S b/lib/libm/arch/amd64/s_ceil.S
new file mode 100644
index 00000000000..05add36fd45
--- /dev/null
+++ b/lib/libm/arch/amd64/s_ceil.S
@@ -0,0 +1,45 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_ceil.S,v 1.7 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(ceil)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0800,%dx /* round towards +oo */
+ andw $0xfbff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ fldl 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ fstcw -12(%rsp)
+ movw -12(%rsp),%dx
+ orw $0x0800,%dx
+ andw $0xfbff,%dx
+ movw %dx,-16(%rsp)
+ fldcw -16(%rsp)
+ movsd %xmm0,-8(%rsp)
+ fldl -8(%rsp)
+ frndint
+ fldcw -12(%rsp)
+ fstpl -8(%rsp)
+ movsd -8(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_ceilf.S b/lib/libm/arch/amd64/s_ceilf.S
new file mode 100644
index 00000000000..4900b42493e
--- /dev/null
+++ b/lib/libm/arch/amd64/s_ceilf.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ceilf.S,v 1.7 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(ceilf)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0800,%dx /* round towards +oo */
+ andw $0xfbff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ flds 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ fstcw -8(%rsp)
+ movw -8(%rsp),%dx
+ orw $0x0800,%dx
+ andw $0xfbff,%dx
+ movw %dx,-12(%rsp)
+ fldcw -12(%rsp)
+ movss %xmm0,-4(%rsp)
+ fldl -4(%rsp)
+ frndint
+ fldcw -8(%rsp)
+ fstps -4(%rsp)
+ movss -4(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_copysign.S b/lib/libm/arch/amd64/s_copysign.S
new file mode 100644
index 00000000000..54f7b15c717
--- /dev/null
+++ b/lib/libm/arch/amd64/s_copysign.S
@@ -0,0 +1,53 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+/*
+ * XXXfvdl might as well split this file.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_copysign.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
+
+#ifdef __x86_64__
+.Lpos:
+ .quad 0x8000000000000000
+.Lneg:
+ .quad 0x7fffffffffffffff
+#endif
+
+
+ENTRY(copysign)
+#ifdef __i386__
+ movl 16(%esp),%edx
+ andl $0x80000000,%edx
+ movl 8(%esp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,8(%esp)
+ fldl 4(%esp)
+#else
+#if 0
+ /*
+ * XXXfvdl gas doesn't grok this yet.
+ */
+ movq .Lpos(%rip),%xmm2
+ movq .Lneg(%rip),%xmm3
+ pand %xmm2,%xmm1
+ pand %xmm3,%xmm0
+ por %xmm1,%xmm0
+#else
+ movsd %xmm0,-8(%rsp)
+ movsd %xmm1,-16(%rsp)
+ movl -12(%rsp),%edx
+ andl $0x80000000,%edx
+ movl -4(%rsp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,-4(%rsp)
+ movsd -8(%rsp),%xmm0
+#endif
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_copysignf.S b/lib/libm/arch/amd64/s_copysignf.S
new file mode 100644
index 00000000000..bbc5dd97dca
--- /dev/null
+++ b/lib/libm/arch/amd64/s_copysignf.S
@@ -0,0 +1,53 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * XXXfvdl split this file.
+ */
+
+RCSID("$NetBSD: s_copysignf.S,v 1.5 2003/07/26 19:25:01 salo Exp $")
+
+#ifdef __x86_64__
+.Lneg:
+ .long 0x7fffffff
+.Lpos:
+ .long 0x80000000
+#endif
+
+ENTRY(copysignf)
+#ifdef __i386__
+ movl 8(%esp),%edx
+ andl $0x80000000,%edx
+ movl 4(%esp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,4(%esp)
+ flds 4(%esp)
+#else
+#if 0
+ /*
+ * XXXfvdl gas doesn't grok this.
+ * but it's legal according to the p4 manual.
+ */
+ movss .Lpos(%rip),%xmm2
+ movss .Lneg(%rip),%xmm3
+ pandq %xmm2,%xmm1
+ pandq %xmm3,%xmm0
+ porq %xmm1,%xmm0
+#else
+ movss %xmm0,-4(%rsp)
+ movss %xmm1,-8(%rsp)
+ movl -8(%rsp),%edx
+ andl $0x80000000,%edx
+ movl -4(%rsp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,-4(%rsp)
+ movss -4(%rsp),%xmm0
+#endif
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_cos.S b/lib/libm/arch/amd64/s_cos.S
new file mode 100644
index 00000000000..b70c5cb3069
--- /dev/null
+++ b/lib/libm/arch/amd64/s_cos.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_cos.S,v 1.8 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(cos)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fcos
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_cosf.S b/lib/libm/arch/amd64/s_cosf.S
new file mode 100644
index 00000000000..3bdcab59e00
--- /dev/null
+++ b/lib/libm/arch/amd64/s_cosf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_cosf.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(cosf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fcos
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_finite.S b/lib/libm/arch/amd64/s_finite.S
new file mode 100644
index 00000000000..73d9cde38b9
--- /dev/null
+++ b/lib/libm/arch/amd64/s_finite.S
@@ -0,0 +1,26 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_finite.S,v 1.7 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(finite)
+#ifdef __i386__
+ movl 8(%esp),%eax
+ andl $0x7ff00000, %eax
+ cmpl $0x7ff00000, %eax
+ setne %al
+ andl $0x000000ff, %eax
+#else
+ xorl %eax,%eax
+ movq $0x7ff0000000000000,%rsi
+ movq %rsi,%rdi
+ movsd %xmm0,-8(%rsp)
+ andq -8(%rsp),%rsi
+ cmpq %rdi,%rsi
+ setne %al
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_finitef.S b/lib/libm/arch/amd64/s_finitef.S
new file mode 100644
index 00000000000..81bf3bd3949
--- /dev/null
+++ b/lib/libm/arch/amd64/s_finitef.S
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_finitef.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(finitef)
+#ifdef __i386__
+ movl 4(%esp),%eax
+ andl $0x7f800000, %eax
+ cmpl $0x7f800000, %eax
+ setne %al
+ andl $0x000000ff, %eax
+#else
+ xorl %eax,%eax
+ movl $0x7ff00000,%esi
+ movss %xmm0,-4(%rsp)
+ andl -4(%rsp),%esi
+ cmpl $0x7ff00000,%esi
+ setne %al
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_floor.S b/lib/libm/arch/amd64/s_floor.S
new file mode 100644
index 00000000000..22da00aacd5
--- /dev/null
+++ b/lib/libm/arch/amd64/s_floor.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floor.S,v 1.8 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(floor)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0400,%dx /* round towards -oo */
+ andw $0xf7ff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ fldl 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ movsd %xmm0, -8(%rsp)
+ fstcw -12(%rsp)
+ movw -12(%rsp),%dx
+ orw $0x0400,%dx
+ andw $0xf7ff,%dx
+ movw %dx,-16(%rsp)
+ fldcw -16(%rsp)
+ fldl -8(%rsp)
+ frndint
+ fldcw -12(%rsp)
+ fstpl -8(%rsp)
+ movsd -8(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_floorf.S b/lib/libm/arch/amd64/s_floorf.S
new file mode 100644
index 00000000000..6a9dab0ca7c
--- /dev/null
+++ b/lib/libm/arch/amd64/s_floorf.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floorf.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(floorf)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0400,%dx /* round towards -oo */
+ andw $0xf7ff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ flds 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ movss %xmm0, -4(%rsp)
+ fstcw -8(%rsp)
+ movw -8(%rsp),%dx
+ orw $0x0400,%dx
+ andw $0xf7ff,%dx
+ movw %dx,-12(%rsp)
+ fldcw -12(%rsp)
+ fldl -4(%rsp)
+ frndint
+ fldcw -8(%rsp)
+ fstpl -4(%rsp)
+ movss -4(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_ilogb.S b/lib/libm/arch/amd64/s_ilogb.S
new file mode 100644
index 00000000000..4bf7da0296b
--- /dev/null
+++ b/lib/libm/arch/amd64/s_ilogb.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogb.S,v 1.7 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(ilogb)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $4,%esp
+
+ fldl 8(%ebp)
+ fxtract
+ fstp %st
+
+ fistpl -4(%ebp)
+ movl -4(%ebp),%eax
+
+ leave
+#else
+ movsd %xmm0,-8(%rsp)
+ fldl -8(%rsp)
+ fxtract
+ fstp %st
+ fistpl -8(%rsp)
+ movl -8(%rsp),%eax
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_ilogbf.S b/lib/libm/arch/amd64/s_ilogbf.S
new file mode 100644
index 00000000000..74e8a9233f8
--- /dev/null
+++ b/lib/libm/arch/amd64/s_ilogbf.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogbf.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(ilogbf)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $4,%esp
+
+ flds 8(%ebp)
+ fxtract
+ fstp %st
+
+ fistpl -4(%ebp)
+ movl -4(%ebp),%eax
+
+ leave
+#else
+ movss %xmm0,-4(%rsp)
+ flds -4(%rsp)
+ fxtract
+ fstp %st
+ fistpl -4(%rsp)
+ movl -4(%rsp),%eax
+#endif
+ ret
diff --git a/lib/libm/arch/amd64/s_log1p.S b/lib/libm/arch/amd64/s_log1p.S
new file mode 100644
index 00000000000..93ab11436e2
--- /dev/null
+++ b/lib/libm/arch/amd64/s_log1p.S
@@ -0,0 +1,76 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+/*
+ * Modified by Lex Wennmacher <wennmach@NetBSD.org>
+ * Still public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_log1p.S,v 1.13 2003/09/16 18:17:11 wennmach Exp $")
+
+/*
+ * The log1p() function is provided to compute an accurate value of
+ * log(1 + x), even for tiny values of x. The i387 FPU provides the
+ * fyl2xp1 instruction for this purpose. However, the range of this
+ * instruction is limited to:
+ * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
+ * -0.292893 <= x <= 0.414214
+ * at least on older processor versions.
+ *
+ * log1p() is implemented by testing the range of the argument.
+ * If it is appropriate for fyl2xp1, this instruction is used.
+ * Else, we compute log1p(x) = ln(2)*ld(1 + x) the traditional way
+ * (using fyl2x).
+ *
+ * The range testing costs speed, but as the rationale for the very
+ * existence of this function is accuracy, we accept that.
+ *
+ * In order to reduce the cost for testing the range, we check if
+ * the argument is in the range
+ * -0.25 <= x <= 0.25
+ * which can be done with just one conditional branch. If x is
+ * inside this range, we use fyl2xp1. Outside of this range,
+ * the use of fyl2x is accurate enough.
+ *
+ */
+
+.text
+ .align 4
+ENTRY(log1p)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fabs
+ fld1 /* ... x 1 */
+ fadd %st(0) /* ... x 2 */
+ fadd %st(0) /* ... x 4 */
+ fld1 /* ... 4 1 */
+ fdivp /* ... x 0.25 */
+ fcompp
+ fnstsw %ax
+ andb $69,%ah
+ jne use_fyl2x
+ jmp use_fyl2xp1
+
+ .align 4
+use_fyl2x:
+ fldln2
+ fldl ARG_DOUBLE_ONE
+ fld1
+ faddp
+ fyl2x
+ XMM_DOUBLE_EPILOGUE
+ ret
+
+ .align 4
+use_fyl2xp1:
+ fldln2
+ fldl ARG_DOUBLE_ONE
+ fyl2xp1
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_log1pf.S b/lib/libm/arch/amd64/s_log1pf.S
new file mode 100644
index 00000000000..3ec415983b4
--- /dev/null
+++ b/lib/libm/arch/amd64/s_log1pf.S
@@ -0,0 +1,76 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+/*
+ * Modified by Lex Wennmacher <wennmach@NetBSD.org>
+ * Still public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_log1pf.S,v 1.10 2003/09/16 18:17:11 wennmach Exp $")
+
+/*
+ * The log1pf() function is provided to compute an accurate value of
+ * log(1 + x), even for tiny values of x. The i387 FPU provides the
+ * fyl2xp1 instruction for this purpose. However, the range of this
+ * instruction is limited to:
+ * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
+ * -0.292893 <= x <= 0.414214
+ * at least on older processor versions.
+ *
+ * log1pf() is implemented by testing the range of the argument.
+ * If it is appropriate for fyl2xp1, this instruction is used.
+ * Else, we compute log1pf(x) = ln(2)*ld(1 + x) the traditional way
+ * (using fyl2x).
+ *
+ * The range testing costs speed, but as the rationale for the very
+ * existence of this function is accuracy, we accept that.
+ *
+ * In order to reduce the cost for testing the range, we check if
+ * the argument is in the range
+ * -0.25 <= x <= 0.25
+ * which can be done with just one conditional branch. If x is
+ * inside this range, we use fyl2xp1. Outside of this range,
+ * the use of fyl2x is accurate enough.
+ *
+ */
+
+.text
+ .align 4
+ENTRY(log1pf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fabs
+ fld1 /* ... x 1 */
+ fadd %st(0) /* ... x 2 */
+ fadd %st(0) /* ... x 4 */
+ fld1 /* ... 4 1 */
+ fdivp /* ... x 0.25 */
+ fcompp
+ fnstsw %ax
+ andb $69,%ah
+ jne use_fyl2x
+ jmp use_fyl2xp1
+
+ .align 4
+use_fyl2x:
+ fldln2
+ flds ARG_FLOAT_ONE
+ fld1
+ faddp
+ fyl2x
+ XMM_FLOAT_EPILOGUE
+ ret
+
+ .align 4
+use_fyl2xp1:
+ fldln2
+ flds ARG_FLOAT_ONE
+ fyl2xp1
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_logb.S b/lib/libm/arch/amd64/s_logb.S
new file mode 100644
index 00000000000..f520248c698
--- /dev/null
+++ b/lib/libm/arch/amd64/s_logb.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_logb.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(logb)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fxtract
+ fstp %st
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_logbf.S b/lib/libm/arch/amd64/s_logbf.S
new file mode 100644
index 00000000000..d66abc21f0f
--- /dev/null
+++ b/lib/libm/arch/amd64/s_logbf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_logbf.S,v 1.5 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(logbf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fxtract
+ fstp %st
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_rint.S b/lib/libm/arch/amd64/s_rint.S
new file mode 100644
index 00000000000..c5300d04d87
--- /dev/null
+++ b/lib/libm/arch/amd64/s_rint.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_rint.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(rint)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ frndint
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_rintf.S b/lib/libm/arch/amd64/s_rintf.S
new file mode 100644
index 00000000000..4ac746fbac7
--- /dev/null
+++ b/lib/libm/arch/amd64/s_rintf.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_rintf.S,v 1.5 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(rintf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ frndint
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_scalbn.S b/lib/libm/arch/amd64/s_scalbn.S
new file mode 100644
index 00000000000..8287145fc1e
--- /dev/null
+++ b/lib/libm/arch/amd64/s_scalbn.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_scalbn.S,v 1.7 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(scalbn)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fildl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+ fscale
+ fstp %st(1) /* bug fix for fp stack overflow */
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_scalbnf.S b/lib/libm/arch/amd64/s_scalbnf.S
new file mode 100644
index 00000000000..af08064de46
--- /dev/null
+++ b/lib/libm/arch/amd64/s_scalbnf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_scalbnf.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(scalbnf)
+ XMM_TWO_ARG_FLOAT_PROLOGUE
+ fildl ARG_FLOAT_TWO
+ flds ARG_FLOAT_ONE
+ fscale
+ fstp %st(1) /* bug fix for fp stack overflow */
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_significand.S b/lib/libm/arch/amd64/s_significand.S
new file mode 100644
index 00000000000..e85763a95c4
--- /dev/null
+++ b/lib/libm/arch/amd64/s_significand.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_significand.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(significand)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fxtract
+ fstp %st(1)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_significandf.S b/lib/libm/arch/amd64/s_significandf.S
new file mode 100644
index 00000000000..126fda10a9c
--- /dev/null
+++ b/lib/libm/arch/amd64/s_significandf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_significandf.S,v 1.5 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(significandf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fxtract
+ fstp %st(1)
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_sin.S b/lib/libm/arch/amd64/s_sin.S
new file mode 100644
index 00000000000..fa6c155da9f
--- /dev/null
+++ b/lib/libm/arch/amd64/s_sin.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_sin.S,v 1.7 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(sin)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fsin
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_sinf.S b/lib/libm/arch/amd64/s_sinf.S
new file mode 100644
index 00000000000..f2cb587aef5
--- /dev/null
+++ b/lib/libm/arch/amd64/s_sinf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_sinf.S,v 1.5 2003/07/26 19:25:04 salo Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(sinf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fsin
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_tan.S b/lib/libm/arch/amd64/s_tan.S
new file mode 100644
index 00000000000..a5bed7b0bfb
--- /dev/null
+++ b/lib/libm/arch/amd64/s_tan.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_tan.S,v 1.7 2003/07/26 19:25:04 salo Exp $")
+
+ENTRY(tan)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fptan
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ fstp %st(0)
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/amd64/s_tanf.S b/lib/libm/arch/amd64/s_tanf.S
new file mode 100644
index 00000000000..a6d6c5b35fc
--- /dev/null
+++ b/lib/libm/arch/amd64/s_tanf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_tanf.S,v 1.5 2003/07/26 19:25:04 salo Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(tanf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fptan
+ fstp %st(0)
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/abi.h b/lib/libm/arch/x86_64/abi.h
new file mode 100644
index 00000000000..cbfbd02c5f5
--- /dev/null
+++ b/lib/libm/arch/x86_64/abi.h
@@ -0,0 +1,73 @@
+/* $NetBSD: abi.h,v 1.2 2003/09/14 21:26:14 fvdl Exp $ */
+
+/*
+ * Written by Frank van der Linden (fvdl@wasabisystems.com)
+ */
+
+/*
+ * The x86-64 ABI specifies that float, double and long double
+ * arguments are passed in SSE2 (xmm) registers. Unfortunately,
+ * there is no way to push those on to the FP stack, which is
+ * where he fancier instructions get their arguments from.
+ *
+ * Define some prologues and epilogues to store and retrieve
+ * xmm regs to local variables.
+ */
+
+#ifdef __x86_64__
+
+#define ARG_DOUBLE_ONE -8(%rsp)
+#define ARG_DOUBLE_TWO -16(%rsp)
+#define ARG_FLOAT_ONE -4(%rsp)
+#define ARG_FLOAT_TWO -8(%rsp)
+
+#define XMM_ONE_ARG_DOUBLE_PROLOGUE \
+ movsd %xmm0, ARG_DOUBLE_ONE
+
+#define XMM_TWO_ARG_DOUBLE_PROLOGUE \
+ movsd %xmm0, ARG_DOUBLE_ONE ; \
+ movsd %xmm1, ARG_DOUBLE_TWO
+
+#define XMM_ONE_ARG_FLOAT_PROLOGUE \
+ movss %xmm0, ARG_FLOAT_ONE
+
+#define XMM_TWO_ARG_FLOAT_PROLOGUE \
+ movss %xmm0, ARG_FLOAT_ONE ; \
+ movss %xmm1, ARG_FLOAT_TWO
+
+#define XMM_DOUBLE_EPILOGUE \
+ fstpl ARG_DOUBLE_ONE ; \
+ movsd ARG_DOUBLE_ONE, %xmm0
+
+#define XMM_FLOAT_EPILOGUE \
+ fstps ARG_FLOAT_ONE ; \
+ movss ARG_FLOAT_ONE, %xmm0
+
+#define FLDL_VAR(x) fldl x(%rip)
+
+#else
+
+#define ARG_DOUBLE_ONE 4(%esp)
+#define ARG_DOUBLE_TWO 12(%esp)
+#define ARG_FLOAT_ONE 4(%esp)
+#define ARG_FLOAT_TWO 8(%esp)
+
+#define XMM_ONE_ARG_DOUBLE_PROLOGUE
+#define XMM_TWO_ARG_DOUBLE_PROLOGUE
+#define XMM_ONE_ARG_FLOAT_PROLOGUE
+#define XMM_TWO_ARG_FLOAT_PROLOGUE
+
+#define XMM_DOUBLE_EPILOGUE
+#define XMM_FLOAT_EPILOGUE
+
+#ifdef PIC
+#define FLDL_VAR(x) \
+ PIC_PROLOGUE ; \
+ fldl PIC_GOTOFF(x) ; \
+ PIC_EPILOGUE
+#else
+#define FLDL_VAR(x) \
+ fldl x
+
+#endif
+#endif
diff --git a/lib/libm/arch/x86_64/e_acos.S b/lib/libm/arch/x86_64/e_acos.S
new file mode 100644
index 00000000000..0c8f20e9a04
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_acos.S
@@ -0,0 +1,24 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_acos.S,v 1.8 2003/07/26 19:24:57 salo Exp $")
+
+/* acos = atan (sqrt(1 - x^2) / x) */
+ENTRY(__ieee754_acos)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE /* x */
+ fld %st(1)
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fxch %st(1)
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_asin.S b/lib/libm/arch/x86_64/e_asin.S
new file mode 100644
index 00000000000..43bea55a236
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_asin.S
@@ -0,0 +1,23 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_asin.S,v 1.7 2003/07/26 19:24:58 salo Exp $")
+
+/* asin = atan (x / sqrt(1 - x^2)) */
+ENTRY(__ieee754_asin)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE /* x */
+ fld %st(0)
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_atan2.S b/lib/libm/arch/x86_64/e_atan2.S
new file mode 100644
index 00000000000..d6d9fa24248
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_atan2.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_atan2.S,v 1.6 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_atan2)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fldl ARG_DOUBLE_TWO
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_atan2f.S b/lib/libm/arch/x86_64/e_atan2f.S
new file mode 100644
index 00000000000..3aed1883532
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_atan2f.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_atan2f.S,v 1.3 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_atan2f)
+ XMM_TWO_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ flds ARG_FLOAT_TWO
+ fpatan
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_exp.S b/lib/libm/arch/x86_64/e_exp.S
new file mode 100644
index 00000000000..cdbc7bd4800
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_exp.S
@@ -0,0 +1,133 @@
+/* $NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $ */
+
+/*
+ * Copyright (c) 1993,94 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Written by:
+ * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $")
+#if 0
+RCSID("$FreeBSD: src/lib/msun/i387/e_exp.S,v 1.8.2.1 2000/07/10 09:16:28 obrien Exp $")
+#endif
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_exp)
+#ifndef __i386__
+ /*
+ * XXX: This code is broken and needs to be merged with the i386 case.
+ */
+ fstcw -12(%rsp)
+ movw -12(%rsp),%dx
+ orw $0x0180,%dx
+ movw %dx,-16(%rsp)
+ fldcw -16(%rsp)
+ movsd %xmm0,-8(%rsp)
+ fldl -8(%rsp)
+
+ fldl2e
+ fmulp /* x * log2(e) */
+ fld %st(0)
+ frndint /* int(x * log2(e)) */
+ fxch %st(1)
+ fsub %st(1),%st /* fract(x * log2(e)) */
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstp %st(1)
+
+ fstpl -8(%rsp)
+ movsd -8(%rsp),%xmm0
+ fldcw -12(%rsp)
+ ret
+#else
+ /*
+ * If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
+ * Avoid this. Also avoid it if x is NaN for convenience.
+ */
+ movl 8(%esp),%eax
+ andl $0x7fffffff,%eax
+ cmpl $0x7ff00000,%eax
+ jae x_Inf_or_NaN
+
+ fldl 4(%esp)
+
+ /*
+ * Ensure that the rounding mode is to nearest (to give the smallest
+ * possible fraction) and that the precision is as high as possible.
+ * We may as well mask interrupts if we switch the mode.
+ */
+ fstcw 4(%esp)
+ movl 4(%esp),%eax
+ andl $0x0300,%eax
+ cmpl $0x0300,%eax /* RC == 0 && PC == 3? */
+ je 1f /* jump if mode is good */
+ movl $0x137f,8(%esp)
+ fldcw 8(%esp)
+1:
+ fldl2e
+ fmulp /* x * log2(e) */
+ fst %st(1)
+ frndint /* int(x * log2(e)) */
+ fst %st(2)
+ fsubrp /* fract(x * log2(e)) */
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstp %st(1)
+ je 1f
+ fldcw 4(%esp)
+1:
+ ret
+
+x_Inf_or_NaN:
+ /*
+ * Return 0 if x is -Inf. Otherwise just return x, although the
+ * C version would return (x + x) (Real Indefinite) if x is a NaN.
+ */
+ cmpl $0xfff00000,8(%esp)
+ jne x_not_minus_Inf
+ cmpl $0,4(%esp)
+ jne x_not_minus_Inf
+ fldz
+ ret
+
+x_not_minus_Inf:
+ fldl 4(%esp)
+ ret
+#endif
diff --git a/lib/libm/arch/x86_64/e_fmod.S b/lib/libm/arch/x86_64/e_fmod.S
new file mode 100644
index 00000000000..4987f9e359c
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_fmod.S
@@ -0,0 +1,23 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+
+RCSID("$NetBSD: e_fmod.S,v 1.7 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_fmod)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+1: fprem
+ fstsw %ax
+ btw $10,%ax
+ jc 1b
+ fstp %st(1)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_log.S b/lib/libm/arch/x86_64/e_log.S
new file mode 100644
index 00000000000..2d773255530
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_log.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_log.S,v 1.6 2003/07/26 19:24:58 salo Exp $")
+
+ENTRY(__ieee754_log)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldln2
+ fldl ARG_DOUBLE_ONE
+ fyl2x
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_log10.S b/lib/libm/arch/x86_64/e_log10.S
new file mode 100644
index 00000000000..ce8e3b93a8e
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_log10.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_log10.S,v 1.6 2003/07/26 19:24:59 salo Exp $")
+
+ENTRY(__ieee754_log10)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldlg2
+ fldl ARG_DOUBLE_ONE
+ fyl2x
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_remainder.S b/lib/libm/arch/x86_64/e_remainder.S
new file mode 100644
index 00000000000..70223b2ad79
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_remainder.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_remainder.S,v 1.7 2003/07/26 19:24:59 salo Exp $")
+
+ENTRY(__ieee754_remainder)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+1: fprem1
+ fstsw %ax
+ btw $10,%ax
+ jc 1b
+ fstp %st(1)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_remainderf.S b/lib/libm/arch/x86_64/e_remainderf.S
new file mode 100644
index 00000000000..aaee4aab044
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_remainderf.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_remainderf.S,v 1.5 2003/07/26 19:24:59 salo Exp $")
+
+ENTRY(__ieee754_remainderf)
+ XMM_TWO_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_TWO
+ flds ARG_FLOAT_ONE
+1: fprem1
+ fstsw %ax
+ btw $10,%ax
+ jc 1b
+ fstp %st(1)
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_scalb.S b/lib/libm/arch/x86_64/e_scalb.S
new file mode 100644
index 00000000000..8717aa7cb03
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_scalb.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: e_scalb.S,v 1.7 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(__ieee754_scalb)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+ fscale
+ fstp %st(1) /* bug fix for fp stack overflow */
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/e_sqrt.S b/lib/libm/arch/x86_64/e_sqrt.S
new file mode 100644
index 00000000000..afae87ffc70
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_sqrt.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrt.S,v 1.6 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(__ieee754_sqrt)
+#ifdef __i386__
+ fldl 4(%esp)
+ fsqrt
+#else
+ sqrtsd %xmm0,%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/e_sqrtf.S b/lib/libm/arch/x86_64/e_sqrtf.S
new file mode 100644
index 00000000000..f9163bab547
--- /dev/null
+++ b/lib/libm/arch/x86_64/e_sqrtf.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrtf.S,v 1.4 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(__ieee754_sqrtf)
+#ifdef __i386__
+ flds 4(%esp)
+ fsqrt
+#else
+ sqrtss %xmm0,%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_atan.S b/lib/libm/arch/x86_64/s_atan.S
new file mode 100644
index 00000000000..61a093309ec
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_atan.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_atan.S,v 1.6 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(atan)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fld1
+ fpatan
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_atanf.S b/lib/libm/arch/x86_64/s_atanf.S
new file mode 100644
index 00000000000..6eec1944ccf
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_atanf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_atanf.S,v 1.5 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(atanf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fld1
+ fpatan
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_ceil.S b/lib/libm/arch/x86_64/s_ceil.S
new file mode 100644
index 00000000000..05add36fd45
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_ceil.S
@@ -0,0 +1,45 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_ceil.S,v 1.7 2003/07/26 19:25:00 salo Exp $")
+
+ENTRY(ceil)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0800,%dx /* round towards +oo */
+ andw $0xfbff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ fldl 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ fstcw -12(%rsp)
+ movw -12(%rsp),%dx
+ orw $0x0800,%dx
+ andw $0xfbff,%dx
+ movw %dx,-16(%rsp)
+ fldcw -16(%rsp)
+ movsd %xmm0,-8(%rsp)
+ fldl -8(%rsp)
+ frndint
+ fldcw -12(%rsp)
+ fstpl -8(%rsp)
+ movsd -8(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_ceilf.S b/lib/libm/arch/x86_64/s_ceilf.S
new file mode 100644
index 00000000000..4900b42493e
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_ceilf.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ceilf.S,v 1.7 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(ceilf)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0800,%dx /* round towards +oo */
+ andw $0xfbff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ flds 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ fstcw -8(%rsp)
+ movw -8(%rsp),%dx
+ orw $0x0800,%dx
+ andw $0xfbff,%dx
+ movw %dx,-12(%rsp)
+ fldcw -12(%rsp)
+ movss %xmm0,-4(%rsp)
+ fldl -4(%rsp)
+ frndint
+ fldcw -8(%rsp)
+ fstps -4(%rsp)
+ movss -4(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_copysign.S b/lib/libm/arch/x86_64/s_copysign.S
new file mode 100644
index 00000000000..54f7b15c717
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_copysign.S
@@ -0,0 +1,53 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+/*
+ * XXXfvdl might as well split this file.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_copysign.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
+
+#ifdef __x86_64__
+.Lpos:
+ .quad 0x8000000000000000
+.Lneg:
+ .quad 0x7fffffffffffffff
+#endif
+
+
+ENTRY(copysign)
+#ifdef __i386__
+ movl 16(%esp),%edx
+ andl $0x80000000,%edx
+ movl 8(%esp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,8(%esp)
+ fldl 4(%esp)
+#else
+#if 0
+ /*
+ * XXXfvdl gas doesn't grok this yet.
+ */
+ movq .Lpos(%rip),%xmm2
+ movq .Lneg(%rip),%xmm3
+ pand %xmm2,%xmm1
+ pand %xmm3,%xmm0
+ por %xmm1,%xmm0
+#else
+ movsd %xmm0,-8(%rsp)
+ movsd %xmm1,-16(%rsp)
+ movl -12(%rsp),%edx
+ andl $0x80000000,%edx
+ movl -4(%rsp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,-4(%rsp)
+ movsd -8(%rsp),%xmm0
+#endif
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_copysignf.S b/lib/libm/arch/x86_64/s_copysignf.S
new file mode 100644
index 00000000000..bbc5dd97dca
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_copysignf.S
@@ -0,0 +1,53 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * XXXfvdl split this file.
+ */
+
+RCSID("$NetBSD: s_copysignf.S,v 1.5 2003/07/26 19:25:01 salo Exp $")
+
+#ifdef __x86_64__
+.Lneg:
+ .long 0x7fffffff
+.Lpos:
+ .long 0x80000000
+#endif
+
+ENTRY(copysignf)
+#ifdef __i386__
+ movl 8(%esp),%edx
+ andl $0x80000000,%edx
+ movl 4(%esp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,4(%esp)
+ flds 4(%esp)
+#else
+#if 0
+ /*
+ * XXXfvdl gas doesn't grok this.
+ * but it's legal according to the p4 manual.
+ */
+ movss .Lpos(%rip),%xmm2
+ movss .Lneg(%rip),%xmm3
+ pandq %xmm2,%xmm1
+ pandq %xmm3,%xmm0
+ porq %xmm1,%xmm0
+#else
+ movss %xmm0,-4(%rsp)
+ movss %xmm1,-8(%rsp)
+ movl -8(%rsp),%edx
+ andl $0x80000000,%edx
+ movl -4(%rsp),%eax
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,-4(%rsp)
+ movss -4(%rsp),%xmm0
+#endif
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_cos.S b/lib/libm/arch/x86_64/s_cos.S
new file mode 100644
index 00000000000..b70c5cb3069
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_cos.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_cos.S,v 1.8 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(cos)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fcos
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_cosf.S b/lib/libm/arch/x86_64/s_cosf.S
new file mode 100644
index 00000000000..3bdcab59e00
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_cosf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_cosf.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(cosf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fcos
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_finite.S b/lib/libm/arch/x86_64/s_finite.S
new file mode 100644
index 00000000000..73d9cde38b9
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_finite.S
@@ -0,0 +1,26 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_finite.S,v 1.7 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(finite)
+#ifdef __i386__
+ movl 8(%esp),%eax
+ andl $0x7ff00000, %eax
+ cmpl $0x7ff00000, %eax
+ setne %al
+ andl $0x000000ff, %eax
+#else
+ xorl %eax,%eax
+ movq $0x7ff0000000000000,%rsi
+ movq %rsi,%rdi
+ movsd %xmm0,-8(%rsp)
+ andq -8(%rsp),%rsi
+ cmpq %rdi,%rsi
+ setne %al
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_finitef.S b/lib/libm/arch/x86_64/s_finitef.S
new file mode 100644
index 00000000000..81bf3bd3949
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_finitef.S
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_finitef.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
+
+ENTRY(finitef)
+#ifdef __i386__
+ movl 4(%esp),%eax
+ andl $0x7f800000, %eax
+ cmpl $0x7f800000, %eax
+ setne %al
+ andl $0x000000ff, %eax
+#else
+ xorl %eax,%eax
+ movl $0x7ff00000,%esi
+ movss %xmm0,-4(%rsp)
+ andl -4(%rsp),%esi
+ cmpl $0x7ff00000,%esi
+ setne %al
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_floor.S b/lib/libm/arch/x86_64/s_floor.S
new file mode 100644
index 00000000000..22da00aacd5
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_floor.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floor.S,v 1.8 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(floor)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0400,%dx /* round towards -oo */
+ andw $0xf7ff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ fldl 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ movsd %xmm0, -8(%rsp)
+ fstcw -12(%rsp)
+ movw -12(%rsp),%dx
+ orw $0x0400,%dx
+ andw $0xf7ff,%dx
+ movw %dx,-16(%rsp)
+ fldcw -16(%rsp)
+ fldl -8(%rsp)
+ frndint
+ fldcw -12(%rsp)
+ fstpl -8(%rsp)
+ movsd -8(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_floorf.S b/lib/libm/arch/x86_64/s_floorf.S
new file mode 100644
index 00000000000..6a9dab0ca7c
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_floorf.S
@@ -0,0 +1,43 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floorf.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(floorf)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+
+ fstcw -4(%ebp) /* store fpu control word */
+ movw -4(%ebp),%dx
+ orw $0x0400,%dx /* round towards -oo */
+ andw $0xf7ff,%dx
+ movw %dx,-8(%ebp)
+ fldcw -8(%ebp) /* load modfied control word */
+
+ flds 8(%ebp); /* round */
+ frndint
+
+ fldcw -4(%ebp) /* restore original control word */
+
+ leave
+#else
+ movss %xmm0, -4(%rsp)
+ fstcw -8(%rsp)
+ movw -8(%rsp),%dx
+ orw $0x0400,%dx
+ andw $0xf7ff,%dx
+ movw %dx,-12(%rsp)
+ fldcw -12(%rsp)
+ fldl -4(%rsp)
+ frndint
+ fldcw -8(%rsp)
+ fstpl -4(%rsp)
+ movss -4(%rsp),%xmm0
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_ilogb.S b/lib/libm/arch/x86_64/s_ilogb.S
new file mode 100644
index 00000000000..4bf7da0296b
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_ilogb.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogb.S,v 1.7 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(ilogb)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $4,%esp
+
+ fldl 8(%ebp)
+ fxtract
+ fstp %st
+
+ fistpl -4(%ebp)
+ movl -4(%ebp),%eax
+
+ leave
+#else
+ movsd %xmm0,-8(%rsp)
+ fldl -8(%rsp)
+ fxtract
+ fstp %st
+ fistpl -8(%rsp)
+ movl -8(%rsp),%eax
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_ilogbf.S b/lib/libm/arch/x86_64/s_ilogbf.S
new file mode 100644
index 00000000000..74e8a9233f8
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_ilogbf.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogbf.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(ilogbf)
+#ifdef __i386__
+ pushl %ebp
+ movl %esp,%ebp
+ subl $4,%esp
+
+ flds 8(%ebp)
+ fxtract
+ fstp %st
+
+ fistpl -4(%ebp)
+ movl -4(%ebp),%eax
+
+ leave
+#else
+ movss %xmm0,-4(%rsp)
+ flds -4(%rsp)
+ fxtract
+ fstp %st
+ fistpl -4(%rsp)
+ movl -4(%rsp),%eax
+#endif
+ ret
diff --git a/lib/libm/arch/x86_64/s_log1p.S b/lib/libm/arch/x86_64/s_log1p.S
new file mode 100644
index 00000000000..93ab11436e2
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_log1p.S
@@ -0,0 +1,76 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+/*
+ * Modified by Lex Wennmacher <wennmach@NetBSD.org>
+ * Still public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_log1p.S,v 1.13 2003/09/16 18:17:11 wennmach Exp $")
+
+/*
+ * The log1p() function is provided to compute an accurate value of
+ * log(1 + x), even for tiny values of x. The i387 FPU provides the
+ * fyl2xp1 instruction for this purpose. However, the range of this
+ * instruction is limited to:
+ * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
+ * -0.292893 <= x <= 0.414214
+ * at least on older processor versions.
+ *
+ * log1p() is implemented by testing the range of the argument.
+ * If it is appropriate for fyl2xp1, this instruction is used.
+ * Else, we compute log1p(x) = ln(2)*ld(1 + x) the traditional way
+ * (using fyl2x).
+ *
+ * The range testing costs speed, but as the rationale for the very
+ * existence of this function is accuracy, we accept that.
+ *
+ * In order to reduce the cost for testing the range, we check if
+ * the argument is in the range
+ * -0.25 <= x <= 0.25
+ * which can be done with just one conditional branch. If x is
+ * inside this range, we use fyl2xp1. Outside of this range,
+ * the use of fyl2x is accurate enough.
+ *
+ */
+
+.text
+ .align 4
+ENTRY(log1p)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fabs
+ fld1 /* ... x 1 */
+ fadd %st(0) /* ... x 2 */
+ fadd %st(0) /* ... x 4 */
+ fld1 /* ... 4 1 */
+ fdivp /* ... x 0.25 */
+ fcompp
+ fnstsw %ax
+ andb $69,%ah
+ jne use_fyl2x
+ jmp use_fyl2xp1
+
+ .align 4
+use_fyl2x:
+ fldln2
+ fldl ARG_DOUBLE_ONE
+ fld1
+ faddp
+ fyl2x
+ XMM_DOUBLE_EPILOGUE
+ ret
+
+ .align 4
+use_fyl2xp1:
+ fldln2
+ fldl ARG_DOUBLE_ONE
+ fyl2xp1
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_log1pf.S b/lib/libm/arch/x86_64/s_log1pf.S
new file mode 100644
index 00000000000..3ec415983b4
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_log1pf.S
@@ -0,0 +1,76 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+/*
+ * Modified by Lex Wennmacher <wennmach@NetBSD.org>
+ * Still public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_log1pf.S,v 1.10 2003/09/16 18:17:11 wennmach Exp $")
+
+/*
+ * The log1pf() function is provided to compute an accurate value of
+ * log(1 + x), even for tiny values of x. The i387 FPU provides the
+ * fyl2xp1 instruction for this purpose. However, the range of this
+ * instruction is limited to:
+ * -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
+ * -0.292893 <= x <= 0.414214
+ * at least on older processor versions.
+ *
+ * log1pf() is implemented by testing the range of the argument.
+ * If it is appropriate for fyl2xp1, this instruction is used.
+ * Else, we compute log1pf(x) = ln(2)*ld(1 + x) the traditional way
+ * (using fyl2x).
+ *
+ * The range testing costs speed, but as the rationale for the very
+ * existence of this function is accuracy, we accept that.
+ *
+ * In order to reduce the cost for testing the range, we check if
+ * the argument is in the range
+ * -0.25 <= x <= 0.25
+ * which can be done with just one conditional branch. If x is
+ * inside this range, we use fyl2xp1. Outside of this range,
+ * the use of fyl2x is accurate enough.
+ *
+ */
+
+.text
+ .align 4
+ENTRY(log1pf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fabs
+ fld1 /* ... x 1 */
+ fadd %st(0) /* ... x 2 */
+ fadd %st(0) /* ... x 4 */
+ fld1 /* ... 4 1 */
+ fdivp /* ... x 0.25 */
+ fcompp
+ fnstsw %ax
+ andb $69,%ah
+ jne use_fyl2x
+ jmp use_fyl2xp1
+
+ .align 4
+use_fyl2x:
+ fldln2
+ flds ARG_FLOAT_ONE
+ fld1
+ faddp
+ fyl2x
+ XMM_FLOAT_EPILOGUE
+ ret
+
+ .align 4
+use_fyl2xp1:
+ fldln2
+ flds ARG_FLOAT_ONE
+ fyl2xp1
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_logb.S b/lib/libm/arch/x86_64/s_logb.S
new file mode 100644
index 00000000000..f520248c698
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_logb.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_logb.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(logb)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fxtract
+ fstp %st
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_logbf.S b/lib/libm/arch/x86_64/s_logbf.S
new file mode 100644
index 00000000000..d66abc21f0f
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_logbf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_logbf.S,v 1.5 2003/07/26 19:25:02 salo Exp $")
+
+ENTRY(logbf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fxtract
+ fstp %st
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_rint.S b/lib/libm/arch/x86_64/s_rint.S
new file mode 100644
index 00000000000..c5300d04d87
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_rint.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_rint.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(rint)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ frndint
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_rintf.S b/lib/libm/arch/x86_64/s_rintf.S
new file mode 100644
index 00000000000..4ac746fbac7
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_rintf.S
@@ -0,0 +1,17 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_rintf.S,v 1.5 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(rintf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ frndint
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_scalbn.S b/lib/libm/arch/x86_64/s_scalbn.S
new file mode 100644
index 00000000000..8287145fc1e
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_scalbn.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_scalbn.S,v 1.7 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(scalbn)
+ XMM_TWO_ARG_DOUBLE_PROLOGUE
+ fildl ARG_DOUBLE_TWO
+ fldl ARG_DOUBLE_ONE
+ fscale
+ fstp %st(1) /* bug fix for fp stack overflow */
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_scalbnf.S b/lib/libm/arch/x86_64/s_scalbnf.S
new file mode 100644
index 00000000000..af08064de46
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_scalbnf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_scalbnf.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(scalbnf)
+ XMM_TWO_ARG_FLOAT_PROLOGUE
+ fildl ARG_FLOAT_TWO
+ flds ARG_FLOAT_ONE
+ fscale
+ fstp %st(1) /* bug fix for fp stack overflow */
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_significand.S b/lib/libm/arch/x86_64/s_significand.S
new file mode 100644
index 00000000000..e85763a95c4
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_significand.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_significand.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(significand)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fxtract
+ fstp %st(1)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_significandf.S b/lib/libm/arch/x86_64/s_significandf.S
new file mode 100644
index 00000000000..126fda10a9c
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_significandf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_significandf.S,v 1.5 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(significandf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fxtract
+ fstp %st(1)
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_sin.S b/lib/libm/arch/x86_64/s_sin.S
new file mode 100644
index 00000000000..fa6c155da9f
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_sin.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_sin.S,v 1.7 2003/07/26 19:25:03 salo Exp $")
+
+ENTRY(sin)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fsin
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_sinf.S b/lib/libm/arch/x86_64/s_sinf.S
new file mode 100644
index 00000000000..f2cb587aef5
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_sinf.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_sinf.S,v 1.5 2003/07/26 19:25:04 salo Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(sinf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fsin
+ XMM_FLOAT_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_tan.S b/lib/libm/arch/x86_64/s_tan.S
new file mode 100644
index 00000000000..a5bed7b0bfb
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_tan.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_tan.S,v 1.7 2003/07/26 19:25:04 salo Exp $")
+
+ENTRY(tan)
+ XMM_ONE_ARG_DOUBLE_PROLOGUE
+ fldl ARG_DOUBLE_ONE
+ fptan
+ fnstsw %ax
+ andw $0x400,%ax
+ jnz 1f
+ fstp %st(0)
+ XMM_DOUBLE_EPILOGUE
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ andw $0x400,%ax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ XMM_DOUBLE_EPILOGUE
+ ret
diff --git a/lib/libm/arch/x86_64/s_tanf.S b/lib/libm/arch/x86_64/s_tanf.S
new file mode 100644
index 00000000000..a6d6c5b35fc
--- /dev/null
+++ b/lib/libm/arch/x86_64/s_tanf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#include "abi.h"
+
+RCSID("$NetBSD: s_tanf.S,v 1.5 2003/07/26 19:25:04 salo Exp $")
+
+/* A float's domain isn't large enough to require argument reduction. */
+ENTRY(tanf)
+ XMM_ONE_ARG_FLOAT_PROLOGUE
+ flds ARG_FLOAT_ONE
+ fptan
+ fstp %st(0)
+ XMM_FLOAT_EPILOGUE
+ ret