Mail Archives: djgpp-workers/2003/03/18/10:08:47
Martin Stromberg wrote:
>But how would you access the bits directly? Doesn't you have to store the float and load it into an unsigned int? Or is there specific CPU instructions for that?
>
Take a look at what I did in the libc math functions. In order to
handle errno properly, I had to do argument tests against infinity and
NaN in virtually all the functions. An argument comes in on the stack,
and you do a move into eax to test the bits, as well as the usual fldl
into the FPU. (After you've got the number into the FPU stack, you can
also do NaN tests with fxam, but they're slower.) In most cases you
only need to examine the most significant longword, rather than the
entire 8 bytes. I would recommend assembler for isnan() and similar
functions -- for these kinds of tests, it's actually more
straightforward and readable than those ugly C casts, and not many more
instructions. Another thing to keep in mind is that if you write the
isnan() macro like this
#define isnan(x) isnand((double) x)
so that it works for floats as well as doubles (where isnand() is a
function that expects a double argument), and you call it like this
float x;
int i;
i = isnan(x);
gcc will generate an flds and an fstl to explicitly convert the argument
from a float to a double, which is fairly time-consuming compared to the
simple integer bit tests. I don't know how to avoid this problem, since
C, unlike FORTRAN, doesn't have type-generic built-in functions. Can
anyone think of a way around this, perhaps using typeof()?
The question also came up about which flavors of NaN to recognize. In
normal FPU computation, the only type of NaN that occurs is the "real
indefinite" non-signalling NaN, which you get, for instance, by
computing 0./0. I think that the penalty for recognizing all the
flavors is that you have to test both upper and lower longwords, rather
than just the most-significant longword. I decided that the extra
effort wasn't justified for the libc math routines, since the other NaNs
aren't supposed to occur anyway, but maybe we want to put the extra code
into an explicit function like isnan().
-Eric
- Raw text -