blob: 395d81c54b0149e764d93ae2598c048f774a3966 [file] [log] [blame]
# With glibc headers, we cannot check __hwcap yet
# Which is fine in this case, as the XMM registers
# were introduced in CPUs starting in 1999.
#ifndef COBALT_MUSL_W_GLIBC_HEADERS
.hidden __hwcap
#endif
.global feclearexcept
.type feclearexcept,@function
feclearexcept:
mov 4(%esp),%ecx
and $0x3f,%ecx
fnstsw %ax
#ifndef COBALT_MUSL_W_GLIBC_HEADERS
# 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
#endif
# 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
ret
.global __fesetround
.type __fesetround,@function
__fesetround:
mov 4(%esp),%ecx
push %eax
xor %eax,%eax
fnstcw (%esp)
andb $0xf3,1(%esp)
or %ch,1(%esp)
fldcw (%esp)
#ifndef COBALT_MUSL_W_GLIBC_HEADERS
# 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
#endif
stmxcsr (%esp)
shl $3,%ch
andb $0x9f,1(%esp)
or %ch,1(%esp)
ldmxcsr (%esp)
1: pop %ecx
ret
.global fegetround
.type fegetround,@function
fegetround:
push %eax
fnstcw (%esp)
pop %eax
and $0xc00,%eax
ret
.global fegetenv
.type fegetenv,@function
fegetenv:
mov 4(%esp),%ecx
xor %eax,%eax
fnstenv (%ecx)
#ifndef COBALT_MUSL_W_GLIBC_HEADERS
# 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
#endif
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
inc %ecx
jz 1f
fldenv -1(%ecx)
movl -1(%ecx),%ecx
jmp 2f
1: push %eax
push %eax
push %eax
push %eax
pushl $0xffff
push %eax
pushl $0x37f
fldenv (%esp)
add $28,%esp
# consider sse fenv as well if the cpu has XMM capability
#ifdef COBALT_MUSL_W_GLIBC_HEADERS
2:
#else
2: call 1f
1: addl $__hwcap-1b,(%esp)
pop %edx
testl $0x02000000,(%edx)
jz 1f
#endif
# 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
# consider sse fenv as well if the cpu has XMM capability
#ifndef COBALT_MUSL_W_GLIBC_HEADERS
call 1f
1: addl $__hwcap-1b,(%esp)
pop %edx
testl $0x02000000,(%edx)
jz 1f
#endif
stmxcsr 4(%esp)
or 4(%esp),%eax
1: and %ecx,%eax
ret