Re: [9fans] more on why vc can't produce amd64 executables
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
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
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
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
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
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
#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