Replace fegetmask() and fesetmask() with feenableexcept(),
fedisableexcept(), and fegetexcept(). These two sets of routines provide the same functionality. I implemented the former as an undocumented internal interface to make the regression test easier to write. However, fe(enable|disable|get)except() is already part of glibc, and I would like to avoid gratuitous differences. The only major flaw in the glibc API is that there's no good way to report errors on processors that don't support all the unmasked exceptions.
This commit is contained in:
parent
f472dda708
commit
6448887f3b
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -109,17 +109,29 @@ feupdateenv(const fenv_t *envp)
|
||||
}
|
||||
|
||||
int
|
||||
__fesetmask(int mask)
|
||||
__feenableexcept(int mask)
|
||||
{
|
||||
struct mask_args p;
|
||||
|
||||
p.mask = mask;
|
||||
sysarch(ALPHA_GET_FPMASK, &p);
|
||||
p.mask |= (mask & FE_ALL_EXCEPT);
|
||||
sysarch(ALPHA_SET_FPMASK, &p);
|
||||
return (p.mask);
|
||||
}
|
||||
|
||||
int
|
||||
__fegetmask(void)
|
||||
__fedisableexcept(int mask)
|
||||
{
|
||||
struct mask_args p;
|
||||
|
||||
sysarch(ALPHA_GET_FPMASK, &p);
|
||||
p.mask &= ~(mask & FE_ALL_EXCEPT);
|
||||
sysarch(ALPHA_SET_FPMASK, &p);
|
||||
return (p.mask);
|
||||
}
|
||||
|
||||
int
|
||||
__fegetexcept(void)
|
||||
{
|
||||
struct mask_args p;
|
||||
|
||||
@ -127,5 +139,6 @@ __fegetmask(void)
|
||||
return (p.mask);
|
||||
}
|
||||
|
||||
__weak_reference(__fesetmask, fesetmask);
|
||||
__weak_reference(__fegetmask, fegetmask);
|
||||
__weak_reference(__feenableexcept, feenableexcept);
|
||||
__weak_reference(__fedisableexcept, fedisableexcept);
|
||||
__weak_reference(__fegetexcept, fegetexcept);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -174,8 +174,9 @@ int feupdateenv(const fenv_t *__envp);
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
int fesetmask(int __mask);
|
||||
int fegetmask(void);
|
||||
int feenableexcept(int __mask);
|
||||
int fedisableexcept(int __mask);
|
||||
int fegetexcept(void);
|
||||
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -113,19 +113,36 @@ feupdateenv(const fenv_t *envp)
|
||||
}
|
||||
|
||||
int
|
||||
__fesetmask(int mask)
|
||||
__feenableexcept(int mask)
|
||||
{
|
||||
int mxcsr, control, omask;
|
||||
|
||||
mask &= FE_ALL_EXCEPT;
|
||||
__fnstcw(&control);
|
||||
__stmxcsr(&mxcsr);
|
||||
omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
|
||||
control = (control | FE_ALL_EXCEPT) & ~mask;
|
||||
control &= ~mask;
|
||||
__fldcw(control);
|
||||
mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
|
||||
mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
|
||||
__ldmxcsr(mxcsr);
|
||||
return (~omask);
|
||||
}
|
||||
|
||||
__weak_reference(__fesetmask, fesetmask);
|
||||
int
|
||||
__fedisableexcept(int mask)
|
||||
{
|
||||
int mxcsr, control, omask;
|
||||
|
||||
mask &= FE_ALL_EXCEPT;
|
||||
__fnstcw(&control);
|
||||
__stmxcsr(&mxcsr);
|
||||
omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
|
||||
control |= mask;
|
||||
__fldcw(control);
|
||||
mxcsr |= mask << _SSE_EMASK_SHIFT;
|
||||
__ldmxcsr(mxcsr);
|
||||
return (~omask);
|
||||
}
|
||||
|
||||
__weak_reference(__feenableexcept, feenableexcept);
|
||||
__weak_reference(__fedisableexcept, fedisableexcept);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -180,10 +180,11 @@ int feupdateenv(const fenv_t *__envp);
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
int fesetmask(int __mask);
|
||||
int feenableexcept(int __mask);
|
||||
int fedisableexcpt(int __mask);
|
||||
|
||||
static __inline int
|
||||
fegetmask(void)
|
||||
fegetexcept(void)
|
||||
{
|
||||
int __control;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -180,19 +180,29 @@ feupdateenv(const fenv_t *__envp)
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
static __inline int
|
||||
fesetmask(int __mask)
|
||||
feenableexcept(int __mask)
|
||||
{
|
||||
fenv_t __fpsr;
|
||||
fenv_t __old_fpsr, __new_fpsr;
|
||||
|
||||
__rfs(&__fpsr);
|
||||
__fpsr &= ~_ENABLE_MASK;
|
||||
__fpsr |= __mask << _FPUSW_SHIFT;
|
||||
__wfs(__fpsr);
|
||||
return (0);
|
||||
__rfs(&__old_fpsr);
|
||||
__new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
|
||||
__wfs(__new_fpsr);
|
||||
return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetmask(void)
|
||||
fedisableexcept(int __mask)
|
||||
{
|
||||
fenv_t __old_fpsr, __new_fpsr;
|
||||
|
||||
__rfs(&__old_fpsr);
|
||||
__new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
|
||||
__wfs(__new_fpsr);
|
||||
return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetexcept(void)
|
||||
{
|
||||
fenv_t __fpsr;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -198,18 +198,29 @@ feupdateenv(const fenv_t *__envp)
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
static __inline int
|
||||
fesetmask(int __mask)
|
||||
feenableexcept(int __mask)
|
||||
{
|
||||
int __control;
|
||||
|
||||
__fnstcw(&__control);
|
||||
__mask = (__control | FE_ALL_EXCEPT) & ~__mask;
|
||||
__mask = __control & ~(__mask & FE_ALL_EXCEPT);
|
||||
__fldcw(__mask);
|
||||
return (~__control & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetmask(void)
|
||||
fedisableexcept(int __mask)
|
||||
{
|
||||
int __control;
|
||||
|
||||
__fnstcw(&__control);
|
||||
__mask = __control | (__mask & FE_ALL_EXCEPT);
|
||||
__fldcw(__mask);
|
||||
return (~__control & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetexcept(void)
|
||||
{
|
||||
int __control;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -205,18 +205,29 @@ int feupdateenv(const fenv_t *__envp);
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
static __inline int
|
||||
fesetmask(int __mask)
|
||||
feenableexcept(int __mask)
|
||||
{
|
||||
fenv_t __newfpsr, __oldfpsr;
|
||||
|
||||
__stfpsr(&__oldfpsr);
|
||||
__newfpsr = (__oldfpsr | FE_ALL_EXCEPT) & ~__mask;
|
||||
__newfpsr = __oldfpsr & ~(__mask & FE_ALL_EXCEPT);
|
||||
__ldfpsr(__newfpsr);
|
||||
return (~__oldfpsr & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetmask(void)
|
||||
fedisableexcept(int __mask)
|
||||
{
|
||||
fenv_t __newfpsr, __oldfpsr;
|
||||
|
||||
__stfpsr(&__oldfpsr);
|
||||
__newfpsr = __oldfpsr | (__mask & FE_ALL_EXCEPT);
|
||||
__ldfpsr(__newfpsr);
|
||||
return (~__oldfpsr & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetexcept(void)
|
||||
{
|
||||
fenv_t __fpsr;
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 8, 2004
|
||||
.Dd March 16, 2005
|
||||
.Dt FENV 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -38,7 +38,10 @@
|
||||
.Nm fegetenv ,
|
||||
.Nm feholdexcept ,
|
||||
.Nm fesetenv ,
|
||||
.Nm feupdateenv
|
||||
.Nm feupdateenv ,
|
||||
.Nm feenableexcept ,
|
||||
.Nm fedisableexcept ,
|
||||
.Nm fegetexcept
|
||||
.Nd floating-point environment control
|
||||
.Sh LIBRARY
|
||||
.Lb libm
|
||||
@ -67,6 +70,12 @@
|
||||
.Fn fesetenv "const fenv_t *envp"
|
||||
.Ft int
|
||||
.Fn feupdateenv "const fenv_t *envp"
|
||||
.Ft int
|
||||
.Fn feenableexcept "int excepts"
|
||||
.Ft int
|
||||
.Fn fedisableexcept "int excepts"
|
||||
.Ft int
|
||||
.Fn fegetexcept "void"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.In fenv.h
|
||||
@ -115,6 +124,17 @@ and
|
||||
.Fn fetestexcept
|
||||
functions to clear, save, raise, restore, and examine the
|
||||
processor's floating-point exception flags, respectively.
|
||||
.Pp
|
||||
Exceptions may be
|
||||
.Em unmasked
|
||||
with
|
||||
.Fn feenableexcept
|
||||
and masked with
|
||||
.Fn fedisableexcept .
|
||||
Unmasked exceptions cause a trap when they are produced, and
|
||||
all exceptions are masked by default.
|
||||
The current mask can be tested with
|
||||
.Fn fegetexcept .
|
||||
.Ss Rounding Modes
|
||||
.St -ieee754
|
||||
specifies four rounding modes.
|
||||
@ -219,7 +239,10 @@ double sqrt(double n) {
|
||||
.Sh SEE ALSO
|
||||
.Xr cc 1 ,
|
||||
.Xr feclearexcept 3 ,
|
||||
.Xr fedisableexcept 3 ,
|
||||
.Xr feenableexcept 3 ,
|
||||
.Xr fegetenv 3 ,
|
||||
.Xr fegetexcept 3 ,
|
||||
.Xr fegetexceptflag 3 ,
|
||||
.Xr fegetround 3 ,
|
||||
.Xr feholdexcept 3 ,
|
||||
@ -229,19 +252,19 @@ double sqrt(double n) {
|
||||
.Xr fesetround 3 ,
|
||||
.Xr fetestexcept 3 ,
|
||||
.Xr feupdateenv 3 ,
|
||||
.Xr fpgetmask 3 ,
|
||||
.Xr fpgetprec 3 ,
|
||||
.Xr fpgetround 3 ,
|
||||
.Xr fpgetsticky 3 ,
|
||||
.Xr fpresetsticky 3 ,
|
||||
.Xr fpsetmask 3 ,
|
||||
.Xr fpsetprec 3 ,
|
||||
.Xr fpsetround 3
|
||||
.Xr fpsetprec 3
|
||||
.Sh STANDARDS
|
||||
Except as noted below,
|
||||
.In fenv.h
|
||||
conforms to
|
||||
.St -isoC-99 .
|
||||
The
|
||||
.Fn feenableexcept ,
|
||||
.Fn fedisableexcept ,
|
||||
and
|
||||
.Fn fegetexcept
|
||||
routines are extensions.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.In fenv.h
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -222,21 +222,33 @@ feupdateenv(const fenv_t *__envp)
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
static __inline int
|
||||
fesetmask(int __mask)
|
||||
feenableexcept(int __mask)
|
||||
{
|
||||
union __fpscr __r;
|
||||
fenv_t __oldmask;
|
||||
|
||||
__mffs(&__r.__d);
|
||||
__oldmask = __r.__bits.__reg;
|
||||
__r.__bits.__reg &= ~_ENABLE_MASK;
|
||||
__r.__bits.__reg |= __mask >> _FPUSW_SHIFT;
|
||||
__r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
|
||||
__mtfsf(__r.__d);
|
||||
return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetmask(void)
|
||||
fedisableexcept(int __mask)
|
||||
{
|
||||
union __fpscr __r;
|
||||
fenv_t __oldmask;
|
||||
|
||||
__mffs(&__r.__d);
|
||||
__oldmask = __r.__bits.__reg;
|
||||
__r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
|
||||
__mtfsf(__r.__d);
|
||||
return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetexcept(void)
|
||||
{
|
||||
union __fpscr __r;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -217,19 +217,29 @@ feupdateenv(const fenv_t *__envp)
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
static __inline int
|
||||
fesetmask(int __mask)
|
||||
feenableexcept(int __mask)
|
||||
{
|
||||
fenv_t __r;
|
||||
fenv_t __old_r, __new_r;
|
||||
|
||||
__stxfsr(&__r);
|
||||
__r &= ~_ENABLE_MASK;
|
||||
__r |= __mask << _FPUSW_SHIFT;
|
||||
__ldxfsr(__r);
|
||||
return (0);
|
||||
__stxfsr(&__old_r);
|
||||
__new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
|
||||
__ldxfsr(__new_r);
|
||||
return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetmask(void)
|
||||
fedisableexcept(int __mask)
|
||||
{
|
||||
fenv_t __old_r, __new_r;
|
||||
|
||||
__stxfsr(&__old_r);
|
||||
__new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
|
||||
__ldxfsr(__new_r);
|
||||
return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fegetexcept(void)
|
||||
{
|
||||
fenv_t __r;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user