In other words, 'stfs' doesn't correctly handle values greater than
MAX_FLOAT, so the 'frsp' is required to ensure that 'stfs' will always
do the right thing.
I would read that differently. Values greater than MAX_FLOAT can simply
not be represented as a single precision float, so both 'frsp' and
'stfs'
must replace the true value with +infinity.
In theory, yes. Here's a message about that bug (although it's related
to very small instead of very big values) from a long time ago on the
mpw-dev list:
********
From: email@hidden
Subject: Re: G4
Date: Wed 28 Nov 2001 09:51:09 CET
To: email@hidden
The bug is for real. Compiler vendors are working around the problem.
Take
the following program.
#include <stdio.h>
int main(void)
{
volatile float f;
double d = 9.4e-78;
f = d;
d = f;
printf("%.6f\n", d);
However, the sequence
frsp fp0,fp31
stfs fp0,56(SP)
could have been simplified to
stfs fp31,56(SP)
If you execute that, the program prints out 1.088446.
One way to see it is to use a hex editor and change
00000014: FC00F818 frsp fp0,fp31
to
00000014: FC00F890 fmr fp0,fp31
It's the store instruction that fails. It stores 0x3F8B522F (it should
be
0x00000000).
Appendix D.7 in Motorola's "PowerPC Microprocessor Family: The
Programming
Environments" specifies The Floating-Point Store Instructions. It goes
into
details about how double-precision data is converted to single-precision
data prior to storing the operands into memory. There are two cases
depending on whether denormalization is required or not. The rules do
not
depend on the Floating-Point Status and Control Register. In particular
does
not dependent on whether it is running in IEEE mode or not.
The appendix ends with the following paragraph:
"It is important to note that for double-precision store floating-point
instructions and for the store floating-point as integer word
instruction no
conversion is required as the data from the FPR is copied directly into
memory."
In my opinion the above means that the frsp should not be needed.
Carsten Hanseen
----------
From: David Henson <email@hidden>
To: All <email@hidden>
Subject: G4
Date: Mon, Nov 26, 2001, 10:43 PM
Sorry if this is a little OT but there seems to be something odd going
on
in the G4 (and G3?), but earlier chips seem to be OK.
Perhaps anyone who knows what I am talking about here could try the
following to see if they get the same result.
There seems to be a problem when saving or restoring very small
floating
point numbers in the short (4 byte) form using stfs and lfs
instructions.
Any number smaller than about 1e-45 seems to give a diferent number
(up to
as large as 1) when one would expect zero.
For Example:-
Somehow create the number 9.4e-78 in a floating point register, say
fp1.
Store it in memory as a 4 byte real using the instruction "stfs", (stfs
fp1,somewhere)
Return it to a register using "lfs", (lfs fp1,somewhere)
Output the result - I get the result 1.088 (it should of course be
zero or
vey close).
Sorry I can not give a C example as I do not use C.