diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-02-08 18:03:51 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-02-08 18:03:51 +0000 |
commit | f9d4dbafe850675850558e2c8597b232b8be0e88 (patch) | |
tree | c7db9cbea87fe13a78bd1aa5a591a820d663b9dc /lib/libm/arch/amd64 | |
parent | d1b83f8bb6e1bc54b2b16eace08563acb5e968a0 (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/libm/arch/amd64')
42 files changed, 1322 insertions, 0 deletions
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 |