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

2013-08-22 Thread Bakul Shah
On Wed, 21 Aug 2013 17:44:03 EDT erik quanstrom quans...@quanstro.net wrote:
 
 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);

Why not
for(i=0; i8; i++) {
Else what is the point of 
c = find1(0x0807060504030201ULL, i+1);
Just eyeballing. I haven't looked at the actual code.



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

2013-08-22 Thread erik quanstrom
  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);
 
 Why not
   for(i=0; i8; i++) {
 Else what is the point of 
   c = find1(0x0807060504030201ULL, i+1);
 Just eyeballing. I haven't looked at the actual code.

as it turns out, floating point is already swapped by Ieee, and
anything less than or equal to 4 bytes is cast uprated to a ulong,
not a uvlong.  

this version produces the same output with -a as on amd64.

i think it's a little more clear to straightforwardly set up the nuxi,
and special case the word-swapping in the floating point.
ideally, the low and high words would be merged to a vlong.

this fix likely won't survive its encounter with review intact, but
at least for now i can compile amd64 binaries on mips.
once a final form is in place a fix should be applied to all
compilers.

- erik


/n/atom/plan9/sys/src/cmd/6l/obj.c:1449,1472 - obj.c:1449,1482
}
  }
  
+ static uvlong lorder = 0x0706050403020100ull;
+ 
  void
+ letab(uchar *t, int w, int n)
+ {
+   uchar *o;
+   uint i;
+ 
+   o = (uchar*)lorder;
+   o += (o[0]!=0)*(8-w);   /* if big endian, use tail not head */
+   for(i = 0; i  n; i++)
+   t[i] = o[i];
+ }
+ 
+ void
  nuxiinit(void)
  {
-   int i, c;
+   int i;
  
-   for(i=0; i4; i++) {
-   c = find1(0x04030201L, i+1);
-   if(i  2)
-   inuxi2[i] = c;
-   if(i  1)
-   inuxi1[i] = c;
-   inuxi4[i] = c;
-   inuxi8[i] = c;
-   inuxi8[i+4] = c+4;
-   fnuxi4[i] = c;
-   fnuxi8[i] = c;
-   fnuxi8[i+4] = c+4;
-   }
+   letab(inuxi1, 4, 1);/* cast to 4 bytes, 1 byte tab 
*/
+   letab(inuxi2, 4, 2);
+   letab(inuxi4, 4, 4);
+   letab(inuxi8, 8, 8);
+   letab(fnuxi4, 4, 4);
+   letab(fnuxi8, 4, 4);/* undo Ieee swapping. */
+   for(i = 4; i  8; i++)
+   fnuxi8[i] = fnuxi8[i-4]+4;
+ 
if(debug['v']) {
Bprint(bso, inuxi = );
for(i=0; i1; i++)
/n/atom/plan9/sys/src/cmd/6l/obj.c:1489,1523 - obj.c:1499,1504
Bprint(bso, \n);
}
Bflush(bso);
- }
- 
- int
- find1(long l, int c)
- {
-   char *p;
-   int i;
- 
-   p = (char*)l;
-   for(i=0; i4; i++)
-   if(*p++ == c)
-   return i;
-   return 0;
- }
- 
- int
- find2(long l, int c)
- {
-   short *p;
-   int i;
- 
-   p = (short*)l;
-   for(i=0; i4; i+=2) {
-   if(((*p  8)  0xff) == c)
-   return i;
-   if((*p++  0xff) == c)
-   return i+1;
-   }
-   return 0;
  }
  
  long



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