math: fix exp2l asm on x86 (raise underflow correctly)
[oweals/musl.git] / src / math / x86_64 / exp2l.s
1 .global expm1l
2 .type expm1l,@function
3 expm1l:
4         fldt 8(%rsp)
5         fldl2e
6         fmulp
7         fld1
8         fld %st(1)
9         fabs
10         fucom %st(1)
11         fnstsw %ax
12         fstp %st(0)
13         fstp %st(0)
14         sahf
15         ja 1f
16         f2xm1
17         ret
18 1:      push %rax
19         call 1f
20         pop %rax
21         fld1
22         fsubrp
23         ret
24
25 .global exp2l
26 .type exp2l,@function
27 exp2l:
28         fldt 8(%rsp)
29 1:      fld %st(0)
30         sub $16,%rsp
31         fstpt (%rsp)
32         mov 8(%rsp),%ax
33         and $0x7fff,%ax
34         cmp $0x3fff+13,%ax
35         jb 4f             # |x| < 8192
36         cmp $0x3fff+15,%ax
37         jae 3f            # |x| >= 32768
38         fsts (%rsp)
39         cmpl $0xc67ff800,(%rsp)
40         jb 2f             # x > -16382
41         movl $0x5f000000,(%rsp)
42         flds (%rsp)       # 0x1p63
43         fld %st(1)
44         fsub %st(1)
45         faddp
46         fucomp %st(1)
47         fnstsw
48         sahf
49         je 2f             # x - 0x1p63 + 0x1p63 == x
50         movl $1,(%rsp)
51         flds (%rsp)       # 0x1p-149
52         fdiv %st(1)
53         fstps (%rsp)      # raise underflow
54 2:      fld1
55         fld %st(1)
56         frndint
57         fxch %st(2)
58         fsub %st(2)       # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
59         f2xm1
60         faddp             # 2^(x-rint(x))
61 1:      fscale
62         fstp %st(1)
63         add $16,%rsp
64         ret
65 3:      xor %eax,%eax
66 4:      cmp $0x3fff-64,%ax
67         fld1
68         jb 1b             # |x| < 0x1p-64
69         fstpt (%rsp)
70         fistl 8(%rsp)
71         fildl 8(%rsp)
72         fsubrp %st(1)
73         addl $0x3fff,8(%rsp)
74         f2xm1
75         fld1
76         faddp             # 2^(x-rint(x))
77         fldt (%rsp)       # 2^rint(x)
78         fmulp
79         add $16,%rsp
80         ret