Date: Mon, 22 Dec 2003 18:46:58 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: "Steven G. Kargl" <kargl@troutmask.apl.washington.edu> Cc: freebsd-standards@freebsd.org Subject: Re: fenv.h implementation questions Message-ID: <20031222182536.C7679@gamplex.bde.org> In-Reply-To: <200312212147.hBLLlGrr028043@troutmask.apl.washington.edu> References: <200312212147.hBLLlGrr028043@troutmask.apl.washington.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031222182536.C7679>