9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] emulated fp on arm
@ 2013-01-28 17:08 erik quanstrom
  2013-01-28 17:10 ` erik quanstrom
  2013-01-29 22:10 ` Richard Miller
  0 siblings, 2 replies; 7+ messages in thread
From: erik quanstrom @ 2013-01-28 17:08 UTC (permalink / raw)
  To: 9fans

speaking of arm issues ...

this problem was causing a script of mine to fail.

kw; awk 'BEGIN {print -1 + 1; if ((-1 + 1) == 0) print "yes"; else print "no"}'
-0
no

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.

here's a fix for the first issue.  it is sufficient to catch the case above.

; diffy -c fpi.h
/n/dump/2013/0125/sys/src/9/omap/fpi.h:37,43 - fpi.h:37,43
  #define	SetQNaN(n)	((n)->s = 0, (n)->e = ExpInfinity, 		\
  			 (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
  #define IsZero(n)	((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
- #define SetZero(n)	((n)->e = 1, (n)->h = 0, (n)->l = 0)
+ #define SetZero(n)	((n)->s = 0, (n)->e = 1, (n)->h = 0, (n)->l = 0)

  /*
   * fpi.c

for maximum completeness, fpicmp could be corrected as follows.
i haven't done this yet since atof(2) doesn't generate them.

int
fpicmp(Internal *x, Internal *y)
{
	if(IsNaN(x) && IsNaN(y))
		return 0;
	if(IsInfinity(x) && IsInfinity(y))
		return y->s - x->s;
	if(x->e == y->e && x->h == y->h && x->l == y->l){
>>		if(IsZero(y))
>>			return 0;
		return y->s - x->s;
	}
	if(x->e < y->e
	   || (x->e == y->e && (x->h < y->h || (x->h == y->h && x->l < y->l))))
		return y->s ? 1: -1;
	return x->s ? -1: 1;
}

- erik



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9fans] emulated fp on arm
  2013-01-28 17:08 [9fans] emulated fp on arm erik quanstrom
@ 2013-01-28 17:10 ` erik quanstrom
  2013-01-29 22:10 ` Richard Miller
  1 sibling, 0 replies; 7+ messages in thread
From: erik quanstrom @ 2013-01-28 17:10 UTC (permalink / raw)
  To: 9fans

> here's a fix for the first issue.  it is sufficient to catch the case above.
>
> ; diffy -c fpi.h
> /n/dump/2013/0125/sys/src/9/omap/fpi.h:37,43 - fpi.h:37,43
>   #define	SetQNaN(n)	((n)->s = 0, (n)->e = ExpInfinity, 		\
>   			 (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
>   #define IsZero(n)	((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
> - #define SetZero(n)	((n)->e = 1, (n)->h = 0, (n)->l = 0)
> + #define SetZero(n)	((n)->s = 0, (n)->e = 1, (n)->h = 0, (n)->l = 0)

i was looking for a little input before submitting.
does anyone see an issue with this?

- erik



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9fans] emulated fp on arm
  2013-01-28 17:08 [9fans] emulated fp on arm erik quanstrom
  2013-01-28 17:10 ` erik quanstrom
@ 2013-01-29 22:10 ` Richard Miller
  2013-01-29 22:44   ` erik quanstrom
  1 sibling, 1 reply; 7+ messages in thread
From: Richard Miller @ 2013-01-29 22:10 UTC (permalink / raw)
  To: 9fans

> 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.

I hope we will soon be emulating vfp floating point instead of the old
arm7500 architecture.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9fans] emulated fp on arm
  2013-01-29 22:10 ` Richard Miller
@ 2013-01-29 22:44   ` erik quanstrom
  2013-01-30 10:35     ` Richard Miller
  2013-01-30 22:18     ` Bakul Shah
  0 siblings, 2 replies; 7+ messages in thread
From: erik quanstrom @ 2013-01-29 22:44 UTC (permalink / raw)
  To: 9fans

On Tue Jan 29 17:12:15 EST 2013, 9fans@hamnavoe.com 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("");
}



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9fans] emulated fp on arm
  2013-01-29 22:44   ` erik quanstrom
@ 2013-01-30 10:35     ` Richard Miller
  2013-01-30 22:18     ` Bakul Shah
  1 sibling, 0 replies; 7+ messages in thread
From: Richard Miller @ 2013-01-30 10:35 UTC (permalink / raw)
  To: 9fans

> ARM 	-1 + 1 = -0 cmp 0 fail; cmp -0 fail
> 	1 + -1 = 0 cmp 0 ok; cmp -0 ok

I know floating point add isn't associative, but I thought it was at
least meant to be commutative.  The bug may not be where you think.

> the fpi guts are independent of the emulation on top, aren't they?

More or less.  There's the question of how many secret extra bits
of precision to maintain internally, beyond the ones you get when
you store from a register.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9fans] emulated fp on arm
  2013-01-29 22:44   ` erik quanstrom
  2013-01-30 10:35     ` Richard Miller
@ 2013-01-30 22:18     ` Bakul Shah
  2013-01-31  3:50       ` erik quanstrom
  1 sibling, 1 reply; 7+ messages in thread
From: Bakul Shah @ 2013-01-30 22:18 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Tue, 29 Jan 2013 17:44:16 EST erik quanstrom <quanstro@quanstro.net> wrote:
> On Tue Jan 29 17:12:15 EST 2013, 9fans@hamnavoe.com 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

As ieee754 (1985):

  When the sum of two operands with opposite signs (or the
  difference of two operands with like signs) is exactly zero,
  the sign of that sum (or difference) shall be + in all
  rounding modes except round toward -INFINITY, in which mode
  that sign shall be -.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9fans] emulated fp on arm
  2013-01-30 22:18     ` Bakul Shah
@ 2013-01-31  3:50       ` erik quanstrom
  0 siblings, 0 replies; 7+ messages in thread
From: erik quanstrom @ 2013-01-31  3:50 UTC (permalink / raw)
  To: 9fans

> As ieee754 (1985):
> 
>   When the sum of two operands with opposite signs (or the
>   difference of two operands with like signs) is exactly zero,
>   the sign of that sum (or difference) shall be + in all
>   rounding modes except round toward -INFINITY, in which mode
>   that sign shall be -.

due to the emulator interface, both cases call fpisub.
i've run a number of tests on this with relatively small
numbers that are equal.  and this seems to solve the
problems without creating new ones.

- erik

; diff -c fpi.c /sys/src/9/omap
fpi.c:137,143 - /sys/src/9/omap/fpi.c:137,142
  void
  fpisub(Internal *x, Internal *y, Internal *i)
  {
- 	int exact;
  	Internal *t;
  
  	if(y->e < x->e
fpi.c:158,164 - /sys/src/9/omap/fpi.c:157,162
  			SetInfinity(i);
  		return;
  	}
- 	exact = x->e == y->e;
  	matchexponents(x, y);
  	i->e = y->e;
  	i->h = y->h - x->h;
fpi.c:167,179 - /sys/src/9/omap/fpi.c:165,172
  		i->l += CarryBit;
  		i->h--;
  	}
- 	if(i->h == 0 && i->l == 0){
+ 	if(i->h == 0 && i->l == 0)
  		SetZero(i);
- 
- 		/* canceling rule */
- 		if(x->s != y->s && exact)
- 			i->s = 0;	/* 1 in round to -∞ mode */
- 	}
  	else while(i->e > 1 && (i->h & HiddenBit) == 0)
  		shift(i);
  }



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-01-31  3:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-28 17:08 [9fans] emulated fp on arm erik quanstrom
2013-01-28 17:10 ` erik quanstrom
2013-01-29 22:10 ` Richard Miller
2013-01-29 22:44   ` erik quanstrom
2013-01-30 10:35     ` Richard Miller
2013-01-30 22:18     ` Bakul Shah
2013-01-31  3:50       ` erik quanstrom

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).