This is the mail archive of the
mailing list for the GCC project.
Re: Processor-specific code
[speaking of an environnement variable used to set IEEE rounding mode]
You'll find that globally changing the rounding mode will screw up
libm functions. Which is pretty much going to make this useless.
Further, when folks need rounding modes other than round-to-nearest,
they tend to need to switch rounding modes during the program too.
For instance, to perform the same calculation with both round-up and
round-down to get error bounds on the calculation.
Thus I think an environment variable to do this is doubly useless.
Understood. I only tried to write that code because the mechanism for
reading these environment variables is already in the source (as well as
documentation on what effect they should have). Currently, when the runtime
library is loaded, it look at:
GFORTRAN_FPU_ROUND: Set floating point rounding. Values are NEAREST, UP,
GFORTRAN_FPU_PRECISION: Precision of intermediate results. Values are 24,
53 and 64.
GFORTRAN_FPU_INVALID: Raise a floating point exception on invalid FP operation.
GFORTRAN_FPU_DENORMAL: Raise a floating point exception when denormal
numbers are encountered.
GFORTRAN_FPU_ZERO: Raise a floating point exception when dividing by zero.
GFORTRAN_FPU_OVERFLOW: Raise a floating point exception on overflow.
GFORTRAN_FPU_UNDERFLOW: Raise a floating point exception on underflow.
GFORTRAN_FPU_PRECISION: Raise a floating point exception on precision loss.
So, if we all agree that some of those are useless, we should remove them
from the code. My humble opinion is:
1. I don't think GFORTRAN_FPU_PRECISION is useful
2. GFORTRAN_FPU_INVALID and all other FPE control options are very
useful, and we want to implement those ones (this is really something one
could want to turn on at runtime, perhaps just to debug one's code).
3. GFORTRAN_FPU_ROUND: I have no precise idea (in the long term, we will
provide subroutines so that the code can control rounding mode).
All that said, C99 has <fenv.h> to control just about anything you
could want about the fpu.
As the linux manpage for "The C99 standard does not define a way to set
individual bits in the floating point mask, e.g. to trap on specific flags."
So, unless I am mistaken, if you want to raise a FPE on dividing by zero,
there is no C99 way to do it.
So I guess we will have to write some non-standard C at some point. Linux
provide feenableexcept, but on darwin I don't know any way to do that
without using assembly code. See Arnaud's link for a compilation of tricks
people have used to do this.