summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/msun/alpha/fenv.c25
-rw-r--r--lib/msun/alpha/fenv.h7
-rw-r--r--lib/msun/amd64/fenv.c27
-rw-r--r--lib/msun/amd64/fenv.h7
-rw-r--r--lib/msun/arm/fenv.h28
-rw-r--r--lib/msun/i387/fenv.h19
-rw-r--r--lib/msun/ia64/fenv.h19
-rw-r--r--lib/msun/man/fenv.341
-rw-r--r--lib/msun/powerpc/fenv.h22
-rw-r--r--lib/msun/sparc64/fenv.h28
10 files changed, 166 insertions, 57 deletions
diff --git a/lib/msun/alpha/fenv.c b/lib/msun/alpha/fenv.c
index 017cd7a..5f0182c 100644
--- a/lib/msun/alpha/fenv.c
+++ b/lib/msun/alpha/fenv.c
@@ -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
+__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
-__fegetmask(void)
+__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);
diff --git a/lib/msun/alpha/fenv.h b/lib/msun/alpha/fenv.h
index 7b79a3f..b940a60 100644
--- a/lib/msun/alpha/fenv.h
+++ b/lib/msun/alpha/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
@@ -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 */
diff --git a/lib/msun/amd64/fenv.c b/lib/msun/amd64/fenv.c
index dd21dad..95c82de 100644
--- a/lib/msun/amd64/fenv.c
+++ b/lib/msun/amd64/fenv.c
@@ -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);
diff --git a/lib/msun/amd64/fenv.h b/lib/msun/amd64/fenv.h
index 29efad9..cbed18e 100644
--- a/lib/msun/amd64/fenv.h
+++ b/lib/msun/amd64/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
@@ -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;
diff --git a/lib/msun/arm/fenv.h b/lib/msun/arm/fenv.h
index 0a99432..d540ae2 100644
--- a/lib/msun/arm/fenv.h
+++ b/lib/msun/arm/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
@@ -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
+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
-fegetmask(void)
+fegetexcept(void)
{
fenv_t __fpsr;
diff --git a/lib/msun/i387/fenv.h b/lib/msun/i387/fenv.h
index 27cd416..2a54c70 100644
--- a/lib/msun/i387/fenv.h
+++ b/lib/msun/i387/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
@@ -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;
diff --git a/lib/msun/ia64/fenv.h b/lib/msun/ia64/fenv.h
index 98992b1..6f0240f 100644
--- a/lib/msun/ia64/fenv.h
+++ b/lib/msun/ia64/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
@@ -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;
diff --git a/lib/msun/man/fenv.3 b/lib/msun/man/fenv.3
index 7c6de1f..1ae0177 100644
--- a/lib/msun/man/fenv.3
+++ b/lib/msun/man/fenv.3
@@ -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
diff --git a/lib/msun/powerpc/fenv.h b/lib/msun/powerpc/fenv.h
index ed9d935..3010472 100644
--- a/lib/msun/powerpc/fenv.h
+++ b/lib/msun/powerpc/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;
diff --git a/lib/msun/sparc64/fenv.h b/lib/msun/sparc64/fenv.h
index b425515..8273299 100644
--- a/lib/msun/sparc64/fenv.h
+++ b/lib/msun/sparc64/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
@@ -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
+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
-fegetmask(void)
+fegetexcept(void)
{
fenv_t __r;
OpenPOWER on IntegriCloud