add -L for generating little-endian code. this is a merger of anyrhine's 0l (he calls it pl) and vl. i'm not convinced that it generates the correct byte order for all header types, but it's what he's been using. i also have no convenient way to test it. Reference: /n/sources/patch/applied/vl-little Date: Sat Mar 25 08:12:40 CET 2006 Signed-off-by: geoff@collyer.net --- /sys/src/cmd/vl/obj.c Sat Mar 25 08:11:03 2006 +++ /sys/src/cmd/vl/obj.c Sat Mar 25 08:10:59 2006 @@ -18,8 +18,11 @@ * -H3 -T0x80020000 -R8 is bootp() format for 4k * -H4 -T0x400000 -R4 is sgi unix coff executable * -H5 -T0x4000A0 -R4 is sgi unix elf executable + * -H6 is headerless */ +int little; + void main(int argc, char *argv[]) { @@ -52,6 +55,11 @@ if(a) INITENTRY = a; break; + case 'L': /* for little-endian mips */ + thechar = '0'; + thestring = "spim"; + little = 1; + break; case 'T': a = ARGF(); if(a) @@ -150,6 +158,15 @@ if(INITRND == -1) INITRND = 0; break; + case 6: /* headerless */ + HEADR = 0; + if(INITTEXT == -1) + INITTEXT = 0x80000000L+HEADR; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4096; + break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", @@ -170,8 +187,12 @@ datap = P; pc = 0; dtype = 4; - if(outfile == 0) - outfile = "v.out"; + if(outfile == 0) { + static char name[20]; + + snprint(name, sizeof name, "%c.out", thechar); + outfile = name; + } cout = create(outfile, 1, 0775); if(cout < 0) { diag("%s: cannot create", outfile); @@ -677,7 +698,7 @@ o = bloc[0]; /* as */ if(o <= AXXX || o >= ALAST) { diag("%s: line %ld: opcode out of range %d", pn, pc-ipc, o); - print(" probably not a .v file\n"); + print(" probably not a .%c file\n", thechar); errorexit(); } if(o == ANAME || o == ASIGNAME) { @@ -1239,17 +1260,27 @@ { int i, c; - for(i=0; i<4; i++) { - c = find1(0x01020304L, i+1); - if(i >= 2) - inuxi2[i-2] = c; - if(i >= 3) - inuxi1[i-3] = c; - inuxi4[i] = c; - - fnuxi8[i] = c+4; - fnuxi8[i+4] = c; - } + for(i=0; i<4; i++) + if (!little) { /* normal big-endian case */ + c = find1(0x01020304L, i+1); + if(i >= 2) + inuxi2[i-2] = c; + if(i >= 3) + inuxi1[i-3] = c; + inuxi4[i] = c; + fnuxi8[i] = c+4; + fnuxi8[i+4] = c; + } else { /* oddball little-endian case */ + c = find1(0x04030201L, i+1); + if(i < 2) + inuxi2[i] = c; + if(i < 1) + inuxi1[i] = c; + inuxi4[i] = c; + fnuxi4[i] = c; + fnuxi8[i] = c; + fnuxi8[i+4] = c+4; + } if(debug['v']) { Bprint(&bso, "inuxi = "); for(i=0; i<1; i++) --- /sys/src/cmd/vl/l.h Sat Mar 25 08:11:16 2006 +++ /sys/src/cmd/vl/l.h Sat Mar 25 08:11:13 2006 @@ -237,6 +237,7 @@ EXTERN char xcmp[32][32]; EXTERN Prog zprg; EXTERN int dtype; +EXTERN int little; EXTERN struct { @@ -298,6 +299,7 @@ void listinit(void); Sym* lookup(char*, int); void lput(long); +void bput(long); void mkfwd(void); void* mysbrk(ulong); void names(void); --- /sys/src/cmd/vl/asm.c Sat Mar 25 08:11:36 2006 +++ /sys/src/cmd/vl/asm.c Sat Mar 25 08:11:30 2006 @@ -13,7 +13,27 @@ OFFSET++;\ */ -#define LPUT(c)\ +#define LPUT(l) { \ + if (little) { \ + LLEPUT(l); \ + } else { \ + LBEPUT(l); \ + } \ + } + +#define LLEPUT(c)\ + {\ + cbp[0] = (c);\ + cbp[1] = (c)>>8;\ + cbp[2] = (c)>>16;\ + cbp[3] = (c)>>24;\ + cbp += 4;\ + cbc -= 4;\ + if(cbc <= 0)\ + cflush();\ + } + +#define LBEPUT(c)\ {\ cbp[0] = (c)>>24;\ cbp[1] = (c)>>16;\ @@ -25,6 +45,7 @@ cflush();\ } + #define CPUT(c)\ {\ cbp[0] = (c);\ @@ -34,6 +55,18 @@ cflush();\ } +void +objput(long l) /* emit long in byte order appropriate to object machine */ +{ + LPUT(l); +} + +void +lput(long l) /* emit long in big-endian byte order */ +{ + LBEPUT(l); +} + long entryvalue(void) { @@ -111,6 +144,7 @@ case 2: case 3: case 5: + case 6: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; @@ -138,6 +172,7 @@ case 2: case 1: case 5: + case 6: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; @@ -203,7 +238,11 @@ lput(0L); /* complete mystery */ break; case 2: - lput(0x407); /* magic */ + if (little) + t = 24; + else + t = 16; + lput(((((4*t)+0)*t)+7)); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); @@ -333,14 +372,15 @@ lput((3L<<16)|0L); /* # Phdrs & Shdr size */ lput((0L<<16)|0L); /* # Shdrs & shdr string size */ - lput(1L); /* text - type = PT_LOAD */ - lput(0L); /* file offset */ - lput(INITTEXT-HEADR); /* vaddr */ - lput(INITTEXT-HEADR); /* paddr */ - lput(HEADR+textsize); /* file size */ - lput(HEADR+textsize); /* memory size */ - lput(0x05L); /* protections = RX */ - lput(0x10000L); /* alignment code?? */ + /* TODO: only these few words are in native byte order? */ + objput(1L); /* text - type = PT_LOAD */ + objput(0L); /* file offset */ + objput(INITTEXT-HEADR); /* vaddr */ + objput(INITTEXT-HEADR); /* paddr */ + objput(HEADR+textsize); /* file size */ + objput(HEADR+textsize); /* memory size */ + objput(0x05L); /* protections = RX */ + objput(0x10000L); /* alignment code?? */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ @@ -359,6 +399,9 @@ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ + break; + case 6: + break; } cflush(); } @@ -375,13 +418,6 @@ } void -lput(long l) -{ - - LPUT(l); -} - -void cflush(void) { int n; @@ -477,7 +513,7 @@ if(t == 'f') s++; - LPUT(v); + LBEPUT(v); if(ver) t += 'a' - 'A'; CPUT(t+0x80); /* 0x80 is variable length */