floating point environment, untested

at present the i386 code does not support sse floating point, which is
not part of the standard i386 abi. while it may be desirable to
support it later, doing so will reduce performance and require some
tricks to probe if sse support is present.

this first commit is i386-only, but it should be trivial to port the
asm to x86_64.
This commit is contained in:
Rich Felker 2011-06-12 15:58:15 -04:00
parent 2afebbbcd1
commit b09b78905b
6 changed files with 144 additions and 0 deletions

View File

@ -0,0 +1,7 @@
#include <fenv.h>
int fegetexceptflag(fexcept_t *fp, int mask)
{
*fp = fetestexcept(mask);
return 0;
}

7
src/fenv/feholdexcept.c Normal file
View File

@ -0,0 +1,7 @@
#include <fenv.h>
int feholdexcept(fenv_t *envp)
{
fegetenv(envp);
return 0;
}

38
src/fenv/fenv.c Normal file
View File

@ -0,0 +1,38 @@
#include <fenv.h>
/* Dummy functions for archs lacking fenv implementation */
int feclearexcept(int mask)
{
return 0;
}
int feraiseexcept(int mask)
{
return 0;
}
int fetestexcept(int mask)
{
return 0;
}
int fegetround(void)
{
return 0;
}
int fesetround(int r)
{
return 0;
}
int fegetenv(fenv_t *envp)
{
return 0;
}
int fesetenv(const fenv_t *envp)
{
return 0;
}

View File

@ -0,0 +1,8 @@
#include <fenv.h>
int fesetexceptflag(const fexcept_t *fp, int mask)
{
feclearexcept(~*fp & mask);
feraiseexcept(*fp & mask);
return 0;
}

9
src/fenv/feupdateenv.c Normal file
View File

@ -0,0 +1,9 @@
#include <fenv.h>
int feupdateenv(const fenv_t *envp)
{
int ex = fetestexcept(FE_ALL_EXCEPT);
fesetenv(envp);
feraiseexcept(ex);
return 0;
}

75
src/fenv/i386/fenv.s Normal file
View File

@ -0,0 +1,75 @@
2: not %ecx
sub $32,%esp
fnstenv (%esp)
and %ecx,4(%esp)
or %edx,4(%esp)
fldenv (%esp)
add $32,%esp
ret
.global feclearexcept
feclearexcept:
xor %eax,%eax
mov 4(%esp),%ecx
xor %edx,%edx
test %ecx,%ecx
jnz 2b
ret
.global feraiseexcept
feraiseexcept:
xor %eax,%eax
mov 4(%esp),%edx
xor %ecx,%ecx
test %edx,%edx
jnz 2b
ret
.global fesetround
fesetround:
xor %eax,%eax
mov $0xc00,%ecx
mov 4(%esp),%edx
jmp 2b
.global fegetround
fegetround:
sub $28,%esp
fnstenv (%esp)
mov 4(%esp),%eax
add $28,%esp
and $0xc,%ah
ret
.global fegetenv
fegetenv:
mov 4(%esp),%ecx
xor %eax,%eax
fnstenv (%ecx)
ret
.global fesetenv
fesetenv:
mov 4(%esp),%ecx
xor %eax,%eax
test %ecx,%ecx
jz 1f
fldenv (%ecx)
ret
1: push %eax
push %eax
push %eax
push %eax
push %eax
push %eax
pushl $0x37f
fldenv (%esp)
add $28,%esp
ret
.global fetestexcept
fetestexcept:
mov 4(%esp),%ecx
fnstsw %ax
and %ecx,%eax
ret