e_exp.S revision 1.14 1 1.14 drochner /* $NetBSD: e_exp.S,v 1.14 2008/06/23 10:24:13 drochner Exp $ */
2 1.12 christos
3 1.12 christos /*
4 1.12 christos * Copyright (c) 1993,94 Winning Strategies, Inc.
5 1.12 christos * All rights reserved.
6 1.12 christos *
7 1.12 christos * Redistribution and use in source and binary forms, with or without
8 1.12 christos * modification, are permitted provided that the following conditions
9 1.12 christos * are met:
10 1.12 christos * 1. Redistributions of source code must retain the above copyright
11 1.12 christos * notice, this list of conditions and the following disclaimer.
12 1.12 christos * 2. Redistributions in binary form must reproduce the above copyright
13 1.12 christos * notice, this list of conditions and the following disclaimer in the
14 1.12 christos * documentation and/or other materials provided with the distribution.
15 1.12 christos * 3. All advertising materials mentioning features or use of this software
16 1.12 christos * must display the following acknowledgement:
17 1.12 christos * This product includes software developed by Winning Strategies, Inc.
18 1.12 christos * 4. The name of the author may not be used to endorse or promote products
19 1.12 christos * derived from this software without specific prior written permission.
20 1.12 christos *
21 1.12 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.12 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.12 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.12 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.12 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.12 christos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.12 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.12 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.12 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 1.12 christos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.12 christos */
32 1.12 christos
33 1.1 jtc /*
34 1.12 christos * Written by:
35 1.12 christos * J.T. Conklin (jtc (at) wimsey.com), Winning Strategies, Inc.
36 1.1 jtc */
37 1.1 jtc
38 1.1 jtc #include <machine/asm.h>
39 1.1 jtc
40 1.10 fvdl #include "abi.h"
41 1.10 fvdl
42 1.14 drochner RCSID("$NetBSD: e_exp.S,v 1.14 2008/06/23 10:24:13 drochner Exp $")
43 1.12 christos #if 0
44 1.12 christos RCSID("$FreeBSD: src/lib/msun/i387/e_exp.S,v 1.8.2.1 2000/07/10 09:16:28 obrien Exp $")
45 1.12 christos #endif
46 1.2 jtc
47 1.1 jtc /* e^x = 2^(x * log2(e)) */
48 1.1 jtc ENTRY(__ieee754_exp)
49 1.13 christos XMM_ONE_ARG_DOUBLE_PROLOGUE
50 1.12 christos /*
51 1.12 christos * If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
52 1.12 christos * Avoid this. Also avoid it if x is NaN for convenience.
53 1.12 christos */
54 1.14 drochner movl ARG_DOUBLE_ONE_MSW, %eax
55 1.13 christos andl $0x7fffffff, %eax
56 1.13 christos cmpl $0x7ff00000, %eax
57 1.12 christos jae x_Inf_or_NaN
58 1.12 christos
59 1.13 christos fldl ARG_DOUBLE_ONE
60 1.12 christos
61 1.12 christos /*
62 1.12 christos * Ensure that the rounding mode is to nearest (to give the smallest
63 1.12 christos * possible fraction) and that the precision is as high as possible.
64 1.12 christos * We may as well mask interrupts if we switch the mode.
65 1.12 christos */
66 1.14 drochner #define CWSTORE_SAV ARG_DOUBLE_ONE_LSW /* XXX overwrites the argument */
67 1.14 drochner #define CWSTORE_TMP ARG_DOUBLE_ONE_MSW
68 1.14 drochner fstcw CWSTORE_SAV
69 1.14 drochner movl CWSTORE_SAV, %eax
70 1.14 drochner andl $0x0f00, %eax
71 1.13 christos cmpl $0x0300, %eax /* RC == 0 && PC == 3? */
72 1.12 christos je 1f /* jump if mode is good */
73 1.14 drochner movl $0x137f, CWSTORE_TMP
74 1.14 drochner fldcw CWSTORE_TMP
75 1.12 christos 1:
76 1.12 christos fldl2e
77 1.12 christos fmulp /* x * log2(e) */
78 1.12 christos fst %st(1)
79 1.12 christos frndint /* int(x * log2(e)) */
80 1.12 christos fst %st(2)
81 1.12 christos fsubrp /* fract(x * log2(e)) */
82 1.12 christos f2xm1 /* 2^(fract(x * log2(e))) - 1 */
83 1.12 christos fld1
84 1.12 christos faddp /* 2^(fract(x * log2(e))) */
85 1.12 christos fscale /* e^x */
86 1.12 christos fstp %st(1)
87 1.12 christos je 1f
88 1.14 drochner fldcw CWSTORE_SAV
89 1.12 christos 1:
90 1.13 christos XMM_DOUBLE_EPILOGUE
91 1.12 christos ret
92 1.12 christos x_Inf_or_NaN:
93 1.12 christos /*
94 1.12 christos * Return 0 if x is -Inf. Otherwise just return x, although the
95 1.12 christos * C version would return (x + x) (Real Indefinite) if x is a NaN.
96 1.12 christos */
97 1.14 drochner cmpl $0xfff00000, ARG_DOUBLE_ONE_MSW
98 1.12 christos jne x_not_minus_Inf
99 1.14 drochner cmpl $0, ARG_DOUBLE_ONE_LSW
100 1.12 christos jne x_not_minus_Inf
101 1.12 christos fldz
102 1.13 christos XMM_DOUBLE_EPILOGUE
103 1.12 christos ret
104 1.12 christos
105 1.12 christos x_not_minus_Inf:
106 1.13 christos fldl ARG_DOUBLE_ONE
107 1.13 christos XMM_DOUBLE_EPILOGUE
108 1.12 christos ret
109