[parisc-linux] floating point exception error
David Huggins-Daines
dhd@linuxcare.com
29 Sep 2000 15:07:29 -0400
David Huggins-Daines <dhd@linuxcare.com> writes:
> GAR! So the problem is obvious. Not only is GCC emitting the wrong
> comparison condition (<> vs. !=), but log(-8.0) is returning a
> signalling NaN on GNU/Linux, and a quiet one on HP/UX:
And yet, not so obvious.
According to the glibc documentation and comments, the GNU libm's
behaviour is correct and the HP/UX behaviour is not.
However, that's okay, because according to the glibc documentation,
the defined IEEE exceptions (the VZOUI bits in the status register)
should *not* cause SIGFPE by default, but should simply set the
appropriate flag bits in the status register. This is consistent with
the behaviour of IEEE compliant floating point on all other GNU/Linux
platforms.
And, guess what, the register dump from the floating point exception
trap handler on Linux *clearly* shows that invalid traps are *not*
enabled in the status word (!!).
This program:
#include <signal.h>
#include <math.h>
double
div_by(x,y)
double x ;
double y ;
{
return x/y ;
}
double overflow(x)
double x ;
{
double y ;
do
{
y = x ;
x *= x ;
} while( y != x ) ;
return x ;
}
int main()
{
union {
double d;
unsigned long long l;
} foo;
div_by(30.0, 0.0);
overflow(1000.0);
foo.d = log(-8.0);
printf("foo.l is %016llx\n", foo.l);
sleep(1);
if (foo.d == foo.d)
return 1;
return 0;
}
Generates the following output on my A180 (with my patch to traps.c to
show floating point status and exceptions):
avalanche:~# ./fptest3
foo.l is 7fffffffffffffff
!!die_if_kernel: fptest3(154): Floating point exception 14
PSW : 0004ff0a GR 1 : fffff000 GR 2 : 000015db GR 3 : 20020100
GR 4 : 40160600 GR 5 : 0000279e GR 6 : 000027b6 GR 7 : 00000001
GR 8 : 00002786 GR 9 : 000a5810 GR10 : 000afcd0 GR11 : 000afe50
GR12 : 00000000 GR13 : ffffffff GR14 : 000afdd0 GR15 : 00000000
GR16 : 000914d0 GR17 : 00000001 GR18 : 20020128 GR19 : 40160600
GR20 : 000000a2 GR21 : 00000000 GR22 : 00000001 GR23 : 00000008
GR24 : 00000000 GR25 : 20020188 GR26 : 20020188 GR27 : 00002758
GR28 : 00000000 GR29 : 00000300 GR30 : 20020180 GR31 : 4006d4df
SR0 : 00000000 SR1 : 00002002 SR2 : 00000000 SR3 : 00002002
SR4 : 00002002 SR5 : 00002002 SR6 : 00002002 SR7 : 00002002
IASQ : 00002002 00002002 IAOQ : 000015e7 000015eb ORIG_R28 : 00000000
IIR : 30002420 ISR : 00002002 IOR : 20020108
Floating point status/exception:
FR0: ec30004000000000
FR1: 26f60c1900000000
FR2: 0000000000000000
FR3: 0000000000000000
Floating point exception
The value of FR0L above can be read as:
flag enable
V Z O U I C . . . . . . . . . . . . . . . RM . . T D V Z O U I
1 1 1 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
| E | C | 3 | 0 | 0 | 0 | 4 | 0 |
As you can see, the I enable bit is zero (so we should NOT have
trapped here according to the architecture manual), the T bit is on
(because obviously we *have* trapped), and the V, Z, O, and I flags
are also on (because we had previously triggered overflow,
div-by-zero, and invalid exceptions).
I have no idea why the exception shows up in FR1L instead of in FR0R
(pipeline mysteries I guess), but anyway that value can be read as:
| 2 | 6 | F | 6 | 0 | C | 1 | 9 |
0 0 1 0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 1
exc | non-opcode bits of instruction
This corresponds to the following instruction:
15e0: 32 f6 0c 19 fcmp,dbl,<> fr23,fr22,
As you can see GCC has generated a trap-on-unordered comparison
condition (<>) here. The HP compiler generates the != condition
instead. However if I hex-edit the binary to change the condition:
15e0: 32 f6 0c 1a fcmp,dbl,!= fr23,fr22,
Then I still get a trap!
Well, on reflection, I notice that the high 6 bits indicate an
Unimplemented exception with opcode 0xC. Yes, "Unimplemented", not
"Invalid". WTF!
So, are unordered comparisons just not handled by the 7300LC? Which
processors are they handled correctly on, if any? Is there any HP
documentation on this? Are there any HP/UX architects in the house? :)
It looks like we are going to need some floating-point completion
support in the kernel, which evidently is going to involve walking the
trap shadow and other fun things I thought you only had to do on DEC
machines ;)
--
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.