Post by Richard Milleri'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.)
Post by Richard MillerI 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("");
}