diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/fenv/fegetexceptflag.c | 7 | ||||
| -rw-r--r-- | src/fenv/feholdexcept.c | 7 | ||||
| -rw-r--r-- | src/fenv/fenv.c | 38 | ||||
| -rw-r--r-- | src/fenv/fesetexceptflag.c | 8 | ||||
| -rw-r--r-- | src/fenv/feupdateenv.c | 9 | ||||
| -rw-r--r-- | src/fenv/i386/fenv.s | 75 | 
6 files changed, 144 insertions, 0 deletions
diff --git a/src/fenv/fegetexceptflag.c b/src/fenv/fegetexceptflag.c new file mode 100644 index 00000000..bab0b44f --- /dev/null +++ b/src/fenv/fegetexceptflag.c @@ -0,0 +1,7 @@ +#include <fenv.h> + +int fegetexceptflag(fexcept_t *fp, int mask) +{ +	*fp = fetestexcept(mask); +	return 0; +} diff --git a/src/fenv/feholdexcept.c b/src/fenv/feholdexcept.c new file mode 100644 index 00000000..4c6da239 --- /dev/null +++ b/src/fenv/feholdexcept.c @@ -0,0 +1,7 @@ +#include <fenv.h> + +int feholdexcept(fenv_t *envp) +{ +	fegetenv(envp); +	return 0; +} diff --git a/src/fenv/fenv.c b/src/fenv/fenv.c new file mode 100644 index 00000000..f77599bc --- /dev/null +++ b/src/fenv/fenv.c @@ -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; +} diff --git a/src/fenv/fesetexceptflag.c b/src/fenv/fesetexceptflag.c new file mode 100644 index 00000000..af5f102d --- /dev/null +++ b/src/fenv/fesetexceptflag.c @@ -0,0 +1,8 @@ +#include <fenv.h> + +int fesetexceptflag(const fexcept_t *fp, int mask) +{ +	feclearexcept(~*fp & mask); +	feraiseexcept(*fp & mask); +	return 0; +} diff --git a/src/fenv/feupdateenv.c b/src/fenv/feupdateenv.c new file mode 100644 index 00000000..50cef8e5 --- /dev/null +++ b/src/fenv/feupdateenv.c @@ -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; +} diff --git a/src/fenv/i386/fenv.s b/src/fenv/i386/fenv.s new file mode 100644 index 00000000..72d2ed7d --- /dev/null +++ b/src/fenv/i386/fenv.s @@ -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  | 
