fix excess precision in return value of i386 log-family functions
[oweals/musl.git] / src / math / i386 / exp.s
1 .global expm1f
2 .type expm1f,@function
3 expm1f:
4         flds 4(%esp)
5         mov 4(%esp),%eax
6         add %eax,%eax
7         cmp $0x01000000,%eax
8         jae 1f
9                 # subnormal x, return x with underflow
10         fld %st(0)
11         fmul %st(1)
12         fstps 4(%esp)
13         ret
14
15 .global expm1l
16 .type expm1l,@function
17 expm1l:
18         fldt 4(%esp)
19         jmp 1f
20
21 .global expm1
22 .type expm1,@function
23 expm1:
24         fldl 4(%esp)
25         mov 8(%esp),%eax
26         add %eax,%eax
27         cmp $0x00200000,%eax
28         jae 1f
29                 # subnormal x, return x with underflow
30         fsts 4(%esp)
31         ret
32 1:      fldl2e
33         fmulp
34         mov $0xc2820000,%eax
35         push %eax
36         flds (%esp)
37         pop %eax
38         fucomp %st(1)
39         fnstsw %ax
40         sahf
41         fld1
42         jb 1f
43                 # x*log2e < -65, return -1 without underflow
44         fstp %st(1)
45         fchs
46         ret
47 1:      fld %st(1)
48         fabs
49         fucom %st(1)
50         fnstsw %ax
51         fstp %st(0)
52         fstp %st(0)
53         sahf
54         ja 1f
55         f2xm1
56         ret
57 1:      call 1f
58         fld1
59         fsubrp
60         ret
61
62 .global exp2f
63 .type exp2f,@function
64 exp2f:
65         flds 4(%esp)
66         jmp 1f
67
68 .global exp2l
69 .global __exp2l
70 .hidden __exp2l
71 .type exp2l,@function
72 exp2l:
73 __exp2l:
74         fldt 4(%esp)
75         jmp 1f
76
77 .global expf
78 .type expf,@function
79 expf:
80         flds 4(%esp)
81         jmp 2f
82
83 .global exp
84 .type exp,@function
85 exp:
86         fldl 4(%esp)
87 2:      fldl2e
88         fmulp
89         jmp 1f
90
91 .global exp2
92 .type exp2,@function
93 exp2:
94         fldl 4(%esp)
95 1:      sub $12,%esp
96         fld %st(0)
97         fstpt (%esp)
98         mov 8(%esp),%ax
99         and $0x7fff,%ax
100         cmp $0x3fff+13,%ax
101         jb 4f             # |x| < 8192
102         cmp $0x3fff+15,%ax
103         jae 3f            # |x| >= 32768
104         fsts (%esp)
105         cmpl $0xc67ff800,(%esp)
106         jb 2f             # x > -16382
107         movl $0x5f000000,(%esp)
108         flds (%esp)       # 0x1p63
109         fld %st(1)
110         fsub %st(1)
111         faddp
112         fucomp %st(1)
113         fnstsw
114         sahf
115         je 2f             # x - 0x1p63 + 0x1p63 == x
116         movl $1,(%esp)
117         flds (%esp)       # 0x1p-149
118         fdiv %st(1)
119         fstps (%esp)      # raise underflow
120 2:      fld1
121         fld %st(1)
122         frndint
123         fxch %st(2)
124         fsub %st(2)       # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
125         f2xm1
126         faddp             # 2^(x-rint(x))
127 1:      fscale
128         fstp %st(1)
129         add $12,%esp
130         ret
131 3:      xor %eax,%eax
132 4:      cmp $0x3fff-64,%ax
133         fld1
134         jb 1b             # |x| < 0x1p-64
135         fstpt (%esp)
136         fistl 8(%esp)
137         fildl 8(%esp)
138         fsubrp %st(1)
139         addl $0x3fff,8(%esp)
140         f2xm1
141         fld1
142         faddp             # 2^(x-rint(x))
143         fldt (%esp)       # 2^rint(x)
144         fmulp
145         add $12,%esp
146         ret