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("");
}

Reply via email to