-2: not %ecx
- sub $32,%esp
- fnstenv (%esp)
- and %ecx,4(%esp)
- or %edx,4(%esp)
- fldenv (%esp)
- add $32,%esp
- ret
+.hidden __hwcap
.global feclearexcept
.type feclearexcept,@function
feclearexcept:
- xor %eax,%eax
mov 4(%esp),%ecx
- xor %edx,%edx
- test %ecx,%ecx
- jnz 2b
+ and $0x3f,%ecx
+ fnstsw %ax
+ # consider sse fenv as well if the cpu has XMM capability
+ call 1f
+1: addl $__hwcap-1b,(%esp)
+ pop %edx
+ testl $0x02000000,(%edx)
+ jz 2f
+ # maintain exceptions in the sse mxcsr, clear x87 exceptions
+ test %eax,%ecx
+ jz 1f
+ fnclex
+1: push %edx
+ stmxcsr (%esp)
+ pop %edx
+ and $0x3f,%eax
+ or %eax,%edx
+ test %edx,%ecx
+ jz 1f
+ not %ecx
+ and %ecx,%edx
+ push %edx
+ ldmxcsr (%esp)
+ pop %edx
+1: xor %eax,%eax
+ ret
+ # only do the expensive x87 fenv load/store when needed
+2: test %eax,%ecx
+ jz 1b
+ not %ecx
+ and %ecx,%eax
+ test $0x3f,%eax
+ jz 1f
+ fnclex
+ jmp 1b
+1: sub $32,%esp
+ fnstenv (%esp)
+ mov %al,4(%esp)
+ fldenv (%esp)
+ add $32,%esp
+ xor %eax,%eax
ret
.global feraiseexcept
.type feraiseexcept,@function
feraiseexcept:
+ mov 4(%esp),%eax
+ and $0x3f,%eax
+ sub $32,%esp
+ fnstenv (%esp)
+ or %al,4(%esp)
+ fldenv (%esp)
+ add $32,%esp
xor %eax,%eax
- mov 4(%esp),%edx
- xor %ecx,%ecx
- test %edx,%edx
- jnz 2b
ret
-.global fesetround
-.type fesetround,@function
-fesetround:
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
mov 4(%esp),%ecx
push %eax
xor %eax,%eax
andb $0xf3,1(%esp)
or %ch,1(%esp)
fldcw (%esp)
- pop %ecx
+ # consider sse fenv as well if the cpu has XMM capability
+ call 1f
+1: addl $__hwcap-1b,(%esp)
+ pop %edx
+ testl $0x02000000,(%edx)
+ jz 1f
+ stmxcsr (%esp)
+ shl $3,%ch
+ andb $0x9f,1(%esp)
+ or %ch,1(%esp)
+ ldmxcsr (%esp)
+1: pop %ecx
ret
.global fegetround
mov 4(%esp),%ecx
xor %eax,%eax
fnstenv (%ecx)
- ret
+ # consider sse fenv as well if the cpu has XMM capability
+ call 1f
+1: addl $__hwcap-1b,(%esp)
+ pop %edx
+ testl $0x02000000,(%edx)
+ jz 1f
+ push %eax
+ stmxcsr (%esp)
+ pop %edx
+ and $0x3f,%edx
+ or %edx,4(%ecx)
+1: ret
.global fesetenv
.type fesetenv,@function
fesetenv:
mov 4(%esp),%ecx
xor %eax,%eax
- test %ecx,%ecx
+ inc %ecx
jz 1f
- fldenv (%ecx)
- ret
+ fldenv -1(%ecx)
+ movl -1(%ecx),%ecx
+ jmp 2f
1: push %eax
push %eax
push %eax
push %eax
- push %eax
+ pushl $0xffff
push %eax
pushl $0x37f
fldenv (%esp)
add $28,%esp
- ret
+ # consider sse fenv as well if the cpu has XMM capability
+2: call 1f
+1: addl $__hwcap-1b,(%esp)
+ pop %edx
+ testl $0x02000000,(%edx)
+ jz 1f
+ # mxcsr := same rounding mode, cleared exceptions, default mask
+ and $0xc00,%ecx
+ shl $3,%ecx
+ or $0x1f80,%ecx
+ mov %ecx,4(%esp)
+ ldmxcsr 4(%esp)
+1: ret
.global fetestexcept
.type fetestexcept,@function
fetestexcept:
mov 4(%esp),%ecx
+ and $0x3f,%ecx
fnstsw %ax
- and %ecx,%eax
+ # consider sse fenv as well if the cpu has XMM capability
+ call 1f
+1: addl $__hwcap-1b,(%esp)
+ pop %edx
+ testl $0x02000000,(%edx)
+ jz 1f
+ stmxcsr 4(%esp)
+ or 4(%esp),%eax
+1: and %ecx,%eax
ret