On Tue Jan 29 17:12:15 EST 2013, [email protected] wrote: > > i'm not a fp expert, but i think there are two problems here. first > > it is bad form to generate -0 in the emulator, even if it is technically > > correct, and second, -0 is defined to be equal to 0 by the spec, so > > -0 == 0 should always be true. > > I think you're right on the second point (I haven't read the IEEE spec > lately, just looked at wikipedia), and wrong on the first. IEEE fp > definitely allows for positive and negative zero, so the emulator should > be generating them when the spec calls for them to do so.
you might be right about the first point, but i'm really having a hard time sorting this out. i don't have the standard, and it's $85. this wiki page says there are some rules funny rules for addition/subtraction: http://en.wikipedia.org/wiki/Signed_zero#Arithmetic here's what i have with the as-is fpi ; for(i in ocilla ladd kw)cpu -h $i -c /tmp/awktest Xeon -1 + 1 = 0 cmp 0 ok; cmp -0 ok 1 + -1 = 0 cmp 0 ok; cmp -0 ok Atom -1 + 1 = 0 cmp 0 ok; cmp -0 ok 1 + -1 = 0 cmp 0 ok; cmp -0 ok ARM -1 + 1 = -0 cmp 0 fail; cmp -0 fail 1 + -1 = 0 cmp 0 ok; cmp -0 ok ; and gcc/amd64 + gawk -1 + 1 = 0 cmp 0 ok; cmp -0 ok if you tell gawk you've got -0, it ignores the sign. in the c world, i couldn't get the same behavior no matter what i set the rounding mode to. (the instruction used is ADDSD.) > I hope we will soon be emulating vfp floating point instead of the old > arm7500 architecture. yes! the fpi guts are independent of the emulation on top, aren't they? i haven't looked too carefully at the inteface. - erik --- ; gcc -c -ggdb -Iplan9/include wierd.c # no optimization ; 9l wierd.o ; ./a.out 0000 0 0.000000 0800 0 0.000000 0400 0 0.000000 0c00 0 0.000000 ; cat wierd.c #include <u.h> #include <libc.h> #include <stdio.h> #include <fenv.h> int tab[] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO, }; void main(void) { int i; double d; for(i = 0; i < nelem(tab); i++){ if(fesetround(tab[i]) != 0) print("can't set mode %d\n", i); d = -1.; d += 1.; print("%.4ux %g %f\n", fegetround(), d, d ); } exits(""); }
