fenv.h implementation questions
Bruce Evans
bde at zeta.org.au
Sun Dec 21 23:47:12 PST 2003
On Sun, 21 Dec 2003, Steven G. Kargl wrote:
> Is the following a sufficient implementation of fenv.h?
> _fenv_t and _fexcept_t would be defined in machine/fenv.h,
> which I haven't implemented, yet. I'm assuming that
> these may be architecture specific (e.g., endianness).
fenv_t and fexcept_t are very MD, and hopefully aren't needed
in more than 1 file, so they should be declared directly in
<machine/fenv.h>.
> SuSv3 states that the exception and rounding mode macros
> are to be defined *if and only if* the implementation
> supports them. It also states that the function prototypes
> that I've include need to be specified. However, why would
> we need to specify, say, fegetround(), if the implementation
> doesn't support control of the rounding mode?
C99 says the same. I guess it is not expected that all rounding
modes are unsupported (after all, there should be a default
rounding mode and even if it is weird than it could be described
by a nonstandard FE_ macro). fegetround() is needed if more than
2 rounding modes are supported and useful for avoiding special
cases if only 1 rounding mode is supported. It is only not useful
if no rounding mode is supported (since then it should not be
called since it has no valid arg).
> Finally, how the heck do we implement the #pragma at the end?
Finish the relevant part of the C99 support in gcc, or wait for it.
I think this is a large task. It would involve turning off certain
optimizations within the FENV_ACCESS ON region.
> #ifndef _FENV_H_
> #define _FENV_H_
>
> #include <sys/cdefs.h>
> #include <machine/fenv.h>
>
> typedef fenv_t _fenv_t;
> typedef fexcept_t _fexcept_t;
>
> #ifdef _EXCEPTIONS
> #define FE_DIVBYZERO 0x00000001 /* Divide by zero */
> #define FE_INEXACT 0x00000002 /* Inexact flag raised */
> #define FE_INVALID 0x00000004 /* Invalid operation */
> #define FE_OVERFLOW 0x00000008 /* Overflow */
> #define FE_UNDERFLOW 0x00000010 /* Underflow */
> #define FE_ALL_EXCEPT 0x0000001F /* Bitwise-or of above flags */
> #endif /* _EXCEPTIONS */
>
> #ifdef _ROUNDING_MODES
> #define FE_DOWNWARD 0x00000020 /* Round downward */
> #define FE_TONEAREST 0x00000040 /* Round to nearest */
> #define FE_TOWARDZERO 0x00000080 /* Round towards zero */
> #define FE_UPWARD 0x00000100 /* Round upwards */
> #endif /* _ROUNDING_MODES */
These should probably all be MD. It saves a negative amount of code to
use a common definition since larger code would be required to convert
between the MI bits and the MI bits.
>
> #define FE_DFL_ENV (fenv_t const *)
This needs to point to something.
>
> #if !defined(_FENV_INLINED_)
> __BEGIN_DECLS
> extern int feclearexcept(int);
> extern int fegetenv(fenv_t *);
> extern int fegetexceptflag(fexcept_t *, int);
> extern int fegetround(void);
> extern int feholdexcept(fenv_t *);
> extern int feraiseexcept(int);
> extern int fesetenv(const fenv_t *);
> extern int fesetexceptflag(const fexcept_t *, int);
> extern int fesetround(int);
> extern int fetestexcept(int);
> extern int feupdateenv(fenv_t *);
> __END_DECLS
> #endif /* !_FENV_INLINED_ */
I don't see much point in inlining these (like the i386 fp* versions).
Marcel pointed out that inline versions are good for backwards
compatibility (the library can be changed without affecting old interfaces),
but we don't need that for standard interfaces.
>
> #if 0
> /* XXX Need to implement the FENV_ACCESS pragma */
> #endif
>
> #endif /* _FENV_H_ */
Bruce
More information about the freebsd-standards
mailing list