optimize x86 feclearexcept: only use save/restore x87 fenv if needed
[musl] / src / fenv / i386 / fenv.s
1 .hidden __hwcap
2
3 .global feclearexcept
4 .type feclearexcept,@function
5 feclearexcept:  
6         mov 4(%esp),%ecx
7         fnstsw %ax
8                 # consider sse fenv as well if the cpu has XMM capability
9         call 1f
10 1:      addl $__hwcap-1b,(%esp)
11         pop %edx
12         testl $0x02000000,(%edx)
13         jz 2f
14                 # maintain exceptions in the sse mxcsr, clear x87 exceptions
15         test %eax,%ecx
16         jz 1f
17         fnclex
18 1:      push %edx
19         stmxcsr (%esp)
20         pop %edx
21         and $0x3f,%eax
22         or %eax,%edx
23         test %edx,%ecx
24         jz 1f
25         not %ecx
26         and %ecx,%edx
27         push %edx
28         ldmxcsr (%esp)
29         pop %edx
30 1:      xor %eax,%eax
31         ret
32                 # only do the expensive x87 fenv load/store when needed
33 2:      test %eax,%ecx
34         jz 1b
35         not %ecx
36         and %ecx,%eax
37         test $0x3f,%eax
38         jz 1f
39         fnclex
40         jmp 1b
41 1:      sub $32,%esp
42         fnstenv (%esp)
43         mov %al,4(%esp)
44         fldenv (%esp)
45         add $32,%esp
46         xor %eax,%eax
47         ret
48
49 .global feraiseexcept
50 .type feraiseexcept,@function
51 feraiseexcept:  
52         mov 4(%esp),%eax
53         sub $32,%esp
54         fnstenv (%esp)
55         or %al,4(%esp)
56         fldenv (%esp)
57         add $32,%esp
58         xor %eax,%eax
59         ret
60
61 .global fesetround
62 .type fesetround,@function
63 fesetround:
64         mov 4(%esp),%ecx
65         push %eax
66         xor %eax,%eax
67         fnstcw (%esp)
68         andb $0xf3,1(%esp)
69         or %ch,1(%esp)
70         fldcw (%esp)
71                 # consider sse fenv as well if the cpu has XMM capability
72         call 1f
73 1:      addl $__hwcap-1b,(%esp)
74         pop %edx
75         testl $0x02000000,(%edx)
76         jmp 1f
77         stmxcsr (%esp)
78         shl $3,%ch
79         andb $0x9f,1(%esp)
80         or %ch,1(%esp)
81         ldmxcsr (%esp)
82 1:      pop %ecx
83         ret
84
85 .global fegetround
86 .type fegetround,@function
87 fegetround:
88         push %eax
89         fnstcw (%esp)
90         pop %eax
91         and $0xc00,%eax
92         ret
93
94 .global fegetenv
95 .type fegetenv,@function
96 fegetenv:
97         mov 4(%esp),%ecx
98         xor %eax,%eax
99         fnstenv (%ecx)
100                 # consider sse fenv as well if the cpu has XMM capability
101         call 1f
102 1:      addl $__hwcap-1b,(%esp)
103         pop %edx
104         testl $0x02000000,(%edx)
105         jz 1f
106         push %eax
107         stmxcsr (%esp)
108         pop %edx
109         and $0x3f,%edx
110         or %edx,4(%ecx)
111 1:      ret
112
113 .global fesetenv
114 .type fesetenv,@function
115 fesetenv:
116         mov 4(%esp),%ecx
117         xor %eax,%eax
118         inc %ecx
119         jz 1f
120         fldenv -1(%ecx)
121         movl -1(%ecx),%ecx
122         jmp 2f
123 1:      push %eax
124         push %eax
125         push %eax
126         push %eax
127         push %eax
128         push %eax
129         pushl $0x37f
130         fldenv (%esp)
131         add $28,%esp
132                 # consider sse fenv as well if the cpu has XMM capability
133 2:      call 1f
134 1:      addl $__hwcap-1b,(%esp)
135         pop %edx
136         testl $0x02000000,(%edx)
137         jz 1f
138                 # mxcsr := same rounding mode, cleared exceptions, default mask
139         and $0xc00,%ecx
140         shl $3,%ecx
141         or $0x1f80,%ecx
142         mov %ecx,4(%esp)
143         ldmxcsr 4(%esp)
144 1:      ret
145
146 .global fetestexcept
147 .type fetestexcept,@function
148 fetestexcept:
149         mov 4(%esp),%ecx
150         fnstsw %ax
151                 # consider sse fenv as well if the cpu has XMM capability
152         call 1f
153 1:      addl $__hwcap-1b,(%esp)
154         pop %edx
155         testl $0x02000000,(%edx)
156         jz 1f
157         stmxcsr 4(%esp)
158         or 4(%esp),%eax
159 1:      and %ecx,%eax
160         ret