Re: [9fans] anchors broken in the g command in sam on p9p?

2013-08-21 Thread Rob Pike
Nothing. That's exactly what ^ and $ do.

-rob



[9fans] comparisons with NaN

2013-08-21 Thread Richard Miller
The Plan 9 C compilers do not appear to be compliant with the IEEE floating
point standard when making comparisons with NaN (not a number) values.

The standard says a comparison with one or both operands NaN is unordered,
ie all relations evaluate to false, except != which is always true.

Testing with this fragment of code:
double a, b;
setfcr(0);
a = 0.0;
b = sqrt(-1.0);
if(a   b) print( (a  b));
if(a = b) print( (a = b));
if(a == b) print( (a == b));
if(a != b) print( (a != b));
if(a = b) print( (a = b));
if(a   b) print( (a  b));
if(b   a) print( (b  a));
if(b = a) print( (b = a));
if(b == a) print( (b == a));
if(b != a) print( (b != a));
if(b = a) print( (b = a));
if(b   a) print( (b  a));
print(\n);
on ARM the result is almost completely wrong:
 (a  b) (a = b) (a != b) (b  a) (b = a) (b != a)
and on x86 the result is even wronger:
 (a  b) (a = b) (a == b) (b  a) (b = a) (b == a)
compared to the IEEE expected result, for example on MacOS:
 (a != b) (b != a)

This was discovered by fgb; I've been looking into the cause -- which is
mainly the assumption, in the compiler and linker, that something like this:
if (a  b) f();
can safely be transformed to this:
if (a = b) goto skip;
f();
skip:
Unfortunately if a or b is NaN, the conditional will be false in both cases.

So is this a feature, or a bug that needs fixing?




Re: [9fans] comparisons with NaN

2013-08-21 Thread erik quanstrom
amd64 does yet something else.

amd64   (a == b) (a = b) (a  b) (b == a) (b = a) (b  a)
386 (a  b) (a = b) (a == b) (b  a) (b = a) (b == a)
arm (a  b) (a = b) (a != b) (b  a) (b = a) (b != a)
mips(a  b) (a = b) (a != b) (b  a) (b = a) (b != a)

 mainly the assumption, in the compiler and linker, that something like this:
   if (a  b) f();
 can safely be transformed to this:
   if (a = b) goto skip;
   f();
   skip:
 Unfortunately if a or b is NaN, the conditional will be false in both cases.
 
 So is this a feature, or a bug that needs fixing?

how about another option, just a bug.

there are other issues with the floating point, including
the fact that -0.0 is transformed both by the compiler, and
by print(2) to 0.0.  ape's printf prints -0.0 correctly.

at least in terms of passing floating point test suites
(like python's) the NaN issue doesn't come up, but the
-0 issue breaks a number of tests.

- erik



Re: [9fans] comparisons with NaN

2013-08-21 Thread erik quanstrom
 how about another option, just a bug.

what i mean is, the need for fixing it depends on how much
havoc this issue causes.

- erik



Re: [9fans] comparisons with NaN

2013-08-21 Thread Richard Miller
 at least in terms of passing floating point test suites
 (like python's) the NaN issue doesn't come up

Actually it was a test suite that revealed the NaN errors.
I wouldn't think it's something anyone needs in normal
day-to-day computation, but sometimes boxes must be ticked.




Re: [9fans] comparisons with NaN

2013-08-21 Thread erik quanstrom
On Wed Aug 21 12:09:26 EDT 2013, 9f...@hamnavoe.com wrote:
  at least in terms of passing floating point test suites
  (like python's) the NaN issue doesn't come up
 
 Actually it was a test suite that revealed the NaN errors.
 I wouldn't think it's something anyone needs in normal
 day-to-day computation, but sometimes boxes must be ticked.

:-)  it is hard to imagine how this is useful.  it's not like
∑{i→∞}-0 is interesting.  at least ∏{i→∞}-0 has an alternating
sign.  (so does it converge with no limit?)

the difference i have seen is a situation like
atan2(-0, x)≡ -π
atan2(+0, x)≡ pi, ∀ x0.

any ideas on how this is useful?

- erik



Re: [9fans] comparisons with NaN

2013-08-21 Thread Bakul Shah
On Aug 21, 2013, at 9:55 AM, erik quanstrom quans...@quanstro.net wrote:

 On Wed Aug 21 12:09:26 EDT 2013, 9f...@hamnavoe.com wrote:
 at least in terms of passing floating point test suites
 (like python's) the NaN issue doesn't come up
 
 Actually it was a test suite that revealed the NaN errors.
 I wouldn't think it's something anyone needs in normal
 day-to-day computation, but sometimes boxes must be ticked.
 
 :-)  it is hard to imagine how this is useful.  it's not like
 ∑{i→∞}-0 is interesting.  at least ∏{i→∞}-0 has an alternating
 sign.  (so does it converge with no limit?)
 
 the difference i have seen is a situation like
   atan2(-0, x)≡ -π
   atan2(+0, x)≡ pi, ∀ x0.
 
 any ideas on how this is useful?


See comments by Stephen Canon in
http://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values

Try this:

#include u.h
#include libc.h

main(){
double a, b;
setfcr(0);
a = 0.0;
b = a/a;
if(a   b) print( (a   b));
if(a = b) print( (a = b));
if(a == b) print( (a == b));
if(a != b) print( (a != b));
if(a = b) print( (a = b));
if(a   b) print( (a   b));
if(b   a) print( (b   a));
if(b = a) print( (b = a));
if(b == a) print( (b == a));
if(b != a) print( (b != a));
if(b = a) print( (b = a));
if(b   a) print( (b   a));
if(b != b) print( (b != b));
if(b == b) print( (b == b));
print(\n);
return 0;
}

It falsely reports b == b when b is NaN. 


Re: [9fans] comparisons with NaN

2013-08-21 Thread erik quanstrom
On Wed Aug 21 13:43:54 EDT 2013, ba...@bitblocks.com wrote:
 On Aug 21, 2013, at 9:55 AM, erik quanstrom quans...@quanstro.net wrote:
 
  On Wed Aug 21 12:09:26 EDT 2013, 9f...@hamnavoe.com wrote:
  at least in terms of passing floating point test suites
  (like python's) the NaN issue doesn't come up
  
  Actually it was a test suite that revealed the NaN errors.
  I wouldn't think it's something anyone needs in normal
  day-to-day computation, but sometimes boxes must be ticked.
  
  :-)  it is hard to imagine how this is useful.  it's not like
  ∑{i→∞}-0 is interesting.  at least ∏{i→∞}-0 has an alternating
  sign.  (so does it converge with no limit?)
  
  the difference i have seen is a situation like
  atan2(-0, x)≡ -π
  atan2(+0, x)≡ pi, ∀ x0.
  
  any ideas on how this is useful?
 
 
 See comments by Stephen Canon in
 http://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values

i think you selected a different antecedent for this than
i did.  by this i ment to refer to -0.

- erik



Re: [9fans] comparisons with NaN

2013-08-21 Thread Bakul Shah
 On Wed Aug 21 13:43:54 EDT 2013, ba...@bitblocks.com wrote:
 On Aug 21, 2013, at 9:55 AM, erik quanstrom quans...@quanstro.net wrote:
 
 On Wed Aug 21 12:09:26 EDT 2013, 9f...@hamnavoe.com wrote:
 
 Actually it was a test suite that revealed the NaN errors.
 I wouldn't think it's something anyone needs in normal
 day-to-day computation, but sometimes boxes must be ticked.
 
 :-)  it is hard to imagine how this is useful.
 
 See comments by Stephen Canon in
 http://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values


That this!






Re: [9fans] comparisons with NaN

2013-08-21 Thread Richard Miller
 by this i ment to refer to -0.

But the subject line says comparisons with NaN.  Start another
thread about signed zero if you like.  (I'm not facing a test
suite objecting to those at the moment.)




Re: [9fans] comparisons with NaN

2013-08-21 Thread lucio
 what i mean is, the need for fixing it depends on how much
 havoc this issue causes.

Well, there is also the question of whether anything at all will break
if the bug is fixed.  If not, then the answer is simple.

++L




Re: [9fans] comparisons with NaN

2013-08-21 Thread Charles Forsyth
I think that if there is a generally-accepted standard for the behaviour of
a language's handling of floating-point numbers,
it would be reasonable to try to follow the standard, unless it's stupid,
ill-advised, or impossible (or all three).
That reply to the Stack Overflow post -- and this might be the first and
last time I can write this -- was, I thought, concise and compelling.


On 21 August 2013 19:00, Richard Miller 9f...@hamnavoe.com wrote:

  by this i ment to refer to -0.

 But the subject line says comparisons with NaN.  Start another
 thread about signed zero if you like.  (I'm not facing a test
 suite objecting to those at the moment.)





Re: [9fans] comparisons with NaN

2013-08-21 Thread erik quanstrom
On Wed Aug 21 14:23:48 EDT 2013, lu...@proxima.alt.za wrote:
  what i mean is, the need for fixing it depends on how much
  havoc this issue causes.
 
 Well, there is also the question of whether anything at all will break
 if the bug is fixed.  If not, then the answer is simple.

fortunately, since plan 9 traps when a computation produces a NaN by default,
and nothing in /sys/src/cmd calls setfcr(2), i think we can exclude this 
possiblity.

- erik



[9fans] more on why vc can't produce amd64 executables

2013-08-21 Thread erik quanstrom
vc vlongs are broken for cast

for example, _v2uc produces the code:

acid; asm(_v2uc)
_v2uc 0x5360MOVWrv+8(FP),R1
_v2uc+0x4 0x5364JMP (R31)
_v2uc+0x8 0x5368AND $0xff,R1

i think this should be
MOVWrv+12(FP),R1
JMP (R31)
AND $0xff,R1

since the high 32-bits of the vlong should be first, since
this is a BE machine.  perhaps there's supposed to be a
special calling convention for vlongs?

here's an example of the issue:

void
main(void)
{
uvlong x;

x = 0x012345678abcdefull;
print((uchar)x %.2ux\n, (uchar)x);
exits();
}

mikro; v.x
x = 0012345678abcdef
(uchar)xef

marshalling a 64-bit pointer in this way will lay down the
bytes with the hi and lo reversed.

- erik



Re: [9fans] more on why vc can't produce amd64 executables

2013-08-21 Thread Bakul Shah
On Wed, 21 Aug 2013 14:36:40 EDT erik quanstrom quans...@quanstro.net wrote:
   uvlong x;
 
   x = 0x012345678abcdefull;
   print((uchar)x %.2ux\n, (uchar)x);
...
 x = 0012345678abcdef
 (uchar)x  ef

You're casting a large int into a small int and this seems right.
Just as (uchar)0x1234 = 0x34

 marshalling a 64-bit pointer in this way will lay down the
 bytes with the hi and lo reversed.

Perhaps you meant to do *(uchar*)x?




Re: [9fans] more on why vc can't produce amd64 executables

2013-08-21 Thread erik quanstrom
 You're casting a large int into a small int and this seems right.
 Just as (uchar)0x1234 = 0x34
 
  marshalling a 64-bit pointer in this way will lay down the
  bytes with the hi and lo reversed.
 
 Perhaps you meant to do *(uchar*)x?

you're right.  what was i thinking.  still, pointers are marshaled wrong.
compiled on mips, this program

#include u.h
#include libc.h

void
main(void)
{
char *p;

p = malloc(100);
print(%p\n, p);
}
does this
; 6.crash
6.crash 203443: suicide: sys: trap: #SS pc=0x2048f2

- erik



Re: [9fans] more on why vc can't produce amd64 executables

2013-08-21 Thread Bakul Shah

On Aug 21, 2013, at 11:57 AM, erik quanstrom quans...@quanstro.net wrote:

 You're casting a large int into a small int and this seems right.
 Just as (uchar)0x1234 = 0x34
 
 marshalling a 64-bit pointer in this way will lay down the
 bytes with the hi and lo reversed.
 
 Perhaps you meant to do *(uchar*)x?

Incidentally, on a little endian machine you'd still get
0xef out of 0x0123456789abcdefull!

 
 you're right.  what was i thinking.  still, pointers are marshaled wrong.

 compiled on mips, this program
 
 #include u.h
 #include libc.h
 
 void
 main(void)
 {
   char *p;
 
   p = malloc(100);
   print(%p\n, p);
 }

 does this
 ; 6.crash
 6.crash 203443: suicide: sys: trap: #SS pc=0x2048f2

How %p is treated is really upto the implementation but
it should not crash since p is never dereferenced. Does
this work?

uintptr q;
print(%p, q);







Re: [9fans] more on why vc can't produce amd64 executables

2013-08-21 Thread erik quanstrom
 How %p is treated is really upto the implementation but
 it should not crash since p is never dereferenced. Does
 this work?
 
   uintptr q;
   print(%p, q);

no.  if i change the print to print an integer, it still fails.

in fact, it's really the indirect call in print that fails.
this is the instruction

CALL*AX

acid; *AX
0x002014b3
acid; src(*AX32)
/sys/src/libc/fmt/dofmt.c:310
 305return _fmtrcpy(f, x, 1);
 306}
 307
 308/* fmt an integer */
 309int
310_ifmt(Fmt *f)
 311{
 312char buf[88], *p, *conv;
 313uvlong vu;
 314ulong u;
 315uintptr pu;

- erik



Re: [9fans] anchors broken in the g command in sam on p9p?

2013-08-21 Thread Rudolf Sykora
On 21 August 2013 07:11, smi...@icebubble.org wrote:

 Maybe someone here can help me make sense of this simple sam session:

 ,c
 this is a file, one of
 many files with singular
 and/or plurals
 .
 ,y/ / g/.+s$/ p
 plurals

 I would expect that to have responded with thisfilesplurals.

,y/ / g/.+s/ p

does it

 According to the docs, g/.+s$/ should check that dot ends with s.

 ,y/ / g/^[ao].*/ p
 singular
 and/or


 I would have thought that would return aoneof.

similarly, I believe
,y/ / g/[ao].*/ p
would do it

I think the pattern in g must match the dot entirely...

(sure, I might be wrong, I haven't tested it thoroughly.)

PS.: I believe there are some dark places in the sam language that can
lead to unexpected behaviour. Particularly the line endings are a
pain.



Re: [9fans] more on why vc can't produce amd64 executables

2013-08-21 Thread erik quanstrom
#include u.h
#include libc.h

void
f(void)
{
write(1, hello\n, 6);
}

void (*call)(void) = f;

void
main(void)
{
call();
exits();
}

the asm is the same when compiled on any arch,

; acid 6.crash4-mips
6.crash4-mips:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid; asm(main)
main 0x0020004e SUBQ$0x8,SP
main+0x4 0x00200052 MOVQcall(SB),AX
main+0xc 0x0020005a CALL*   AX
main+0xe 0x0020005c MOVL$.string+0x7(SB),BP
main+0x13 0x00200061CALLexits(SB)
main+0x18 0x00200066ADDQ$0x8,SP
main+0x1c 0x0020006aRET
_main 0x0020006bSUBQ$0x90,SP

but the data is incorrect in the mips-compiled binary.
acid; *(call\Y)
0x00200028

mikro; diff -c crash4-mipsa crash4-amd64a
crash4-mipsa:417,423 - crash4-amd64a:417,423
  2005af 48c7c53200 (4) MOVQ$50,BP
  2005b6 0f05   (5) SYSCALL ,
  2005b8 c3 (6) RET ,
- 400010 28002000   (823)   DATAcall+0(SB)/8,$f+0(SB)
+ 400010 28002000   (823)   DATAcall+0(SB)/8,$f+0(SB)
  400030 68656c6c6f0a   (829)   DATA
.string1+0(SB)/8,$hello\n\z\z
  400028 6d61696e   (18)DATA_exits2+0(SB)/4,$main\z\z\z\z
  40 23632f706964   (829)   DATA.string7+0(SB)/8,$#c/pid\z\z

i think a bug is setting inuxi8[i+4] = inuxi8[i] for 0=i4.
mikro; diffy -c *.c
diff -c /n/dump/2013/0821/sys/src/cmd/6l/obj.c obj.c
/n/dump/2013/0821/sys/src/cmd/6l/obj.c:1455,1471 - obj.c:1455,1471
int i, c;
  
for(i=0; i4; i++) {
-   c = find1(0x04030201L, i+1);
+   c = find1(0x0807060504030201ULL, i+1);
if(i  2)
inuxi2[i] = c;
if(i  1)
inuxi1[i] = c;
-   inuxi4[i] = c;
+   if(i  4){
+   inuxi4[i] = c;
+   fnuxi4[i] = c;
+   }
inuxi8[i] = c;
-   inuxi8[i+4] = c+4;
-   fnuxi4[i] = c;
fnuxi8[i] = c;
-   fnuxi8[i+4] = c+4;
}
if(debug['v']) {
Bprint(bso, inuxi = );
/n/dump/2013/0821/sys/src/cmd/6l/obj.c:1492,1504 - obj.c:1492,1504
  }
  
  int
- find1(long l, int c)
+ find1(uvlong l, int c)
  {
char *p;
int i;
  
p = (char*)l;
-   for(i=0; i4; i++)
+   for(i=0; i8; i++)
if(*p++ == c)
return i;
return 0;
/n/dump/2013/0821/sys/src/cmd/6l/obj.c:1505,1517 - obj.c:1505,1517
  }
  
  int
- find2(long l, int c)
+ find2(uvlong l, int c)
  {
short *p;
int i;
  
p = (short*)l;
-   for(i=0; i4; i+=2) {
+   for(i=0; i8; i+=2) {
if(((*p  8)  0xff) == c)
return i;
if((*p++  0xff) == c)


unfortunately, compiling on mips *still* doesn't work right.
print prints %%p for %p.  i don't know if my fix is wrong, or
if there is another bug.

- erik