diff options
| author | forsyth <forsyth@vitanuova.com> | 2010-04-27 21:15:13 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2010-04-27 21:15:13 +0100 |
| commit | c0927006217e7a7e0214add5828659287c7498d6 (patch) | |
| tree | 528acb9e0df2d33eaa2481b8e3ff37c252082fd2 | |
| parent | 2303ddadf6e5cbf9705ccf25abe6114af1126b79 (diff) | |
20100427-2115
| -rw-r--r-- | utils/8c/8.out.h | 2 | ||||
| -rw-r--r-- | utils/8c/cgen.c | 2 | ||||
| -rw-r--r-- | utils/8c/cgen64.c | 14 | ||||
| -rw-r--r-- | utils/8c/gc.h | 3 | ||||
| -rw-r--r-- | utils/8c/mkfile | 8 | ||||
| -rw-r--r-- | utils/8c/peep.c | 2 | ||||
| -rw-r--r-- | utils/8c/sgen.c | 412 | ||||
| -rw-r--r-- | utils/8c/swt.c | 128 | ||||
| -rw-r--r-- | utils/8c/txt.c | 60 | ||||
| -rw-r--r-- | utils/8l/asm.c | 160 | ||||
| -rw-r--r-- | utils/8l/l.h | 7 | ||||
| -rw-r--r-- | utils/8l/list.c | 2 | ||||
| -rw-r--r-- | utils/8l/obj.c | 20 | ||||
| -rw-r--r-- | utils/8l/pass.c | 7 | ||||
| -rw-r--r-- | utils/8l/span.c | 4 | ||||
| -rw-r--r-- | utils/kl/span.c | 2 |
16 files changed, 193 insertions, 640 deletions
diff --git a/utils/8c/8.out.h b/utils/8c/8.out.h index fdfd0ca7..c38ab83f 100644 --- a/utils/8c/8.out.h +++ b/utils/8c/8.out.h @@ -420,7 +420,7 @@ enum T_SYM = 1<<4, T_SCONST = 1<<5, - REGARG = 0, + REGARG = -1, REGRET = D_AX, FREGRET = D_F0, REGSP = D_SP, diff --git a/utils/8c/cgen.c b/utils/8c/cgen.c index 81521666..c8511e2c 100644 --- a/utils/8c/cgen.c +++ b/utils/8c/cgen.c @@ -895,7 +895,7 @@ cgen(Node *n, Node *nn) regfree(&nod); } else gopcode(OFUNC, n->type, Z, l); - if(REGARG && reg[REGARG]) + if(REGARG>=0 && reg[REGARG]) reg[REGARG]--; if(nn != Z) { regret(&nod, n); diff --git a/utils/8c/cgen64.c b/utils/8c/cgen64.c index 6a1e835e..dd82adfa 100644 --- a/utils/8c/cgen64.c +++ b/utils/8c/cgen64.c @@ -2681,7 +2681,19 @@ void testv(Node *n, int true) { Type *t; - Node *nn, nod; + Node *nn, nod, *b; + + if(machcap(Z)) { + b = &nod; + b->op = true ? ONE : OEQ; + b->left = n; + b->right = new(0, Z, Z); + *b->right = *nodconst(0); + b->right->type = n->type; + b->type = types[TLONG]; + cgen64(b, Z); + return; + } switch(n->op) { case OINDREG: diff --git a/utils/8c/gc.h b/utils/8c/gc.h index b6050d82..b7257962 100644 --- a/utils/8c/gc.h +++ b/utils/8c/gc.h @@ -64,6 +64,7 @@ struct Case long val; long label; char def; + char isv; }; #define C ((Case*)0) @@ -131,6 +132,7 @@ struct Rgn }; EXTERN long breakpc; +EXTERN long nbreak; EXTERN Case* cases; EXTERN Node constnode; EXTERN Node fconstnode; @@ -141,7 +143,6 @@ EXTERN Prog* firstp; EXTERN Prog* lastp; EXTERN long maxargsafe; EXTERN int mnstring; -EXTERN int retok; EXTERN Node* nodrat; EXTERN Node* nodret; EXTERN Node* nodsafe; diff --git a/utils/8c/mkfile b/utils/8c/mkfile index 729cff24..2bafc9ee 100644 --- a/utils/8c/mkfile +++ b/utils/8c/mkfile @@ -11,6 +11,8 @@ OFILES=\ txt.$O\ reg.$O\ peep.$O\ + pgen.$O\ + pswt.$O\ machcap.$O\ cgen64.$O\ div.$O\ @@ -33,3 +35,9 @@ $ROOT/$OBJDIR/lib/libcc.a: cd ../cc mk $MKFLAGS install mk $MKFLAGS clean + +%.$O: ../cc/%.c + $CC $CFLAGS -I. ../cc/$stem.c + +#enam.c: 8.out.h +# rc mkenam diff --git a/utils/8c/peep.c b/utils/8c/peep.c index 8a2d79b7..ed3e6b78 100644 --- a/utils/8c/peep.c +++ b/utils/8c/peep.c @@ -669,7 +669,7 @@ copyu(Prog *p, Adr *v, Adr *s) return 3; case ACALL: /* funny */ - if(REGARG && v->type == REGARG) + if(REGARG>=0 && v->type == REGARG) return 2; if(s != A) { diff --git a/utils/8c/sgen.c b/utils/8c/sgen.c index e6282b21..df12f903 100644 --- a/utils/8c/sgen.c +++ b/utils/8c/sgen.c @@ -1,385 +1,6 @@ #include "gc.h" void -codgen(Node *n, Node *nn) -{ - Prog *sp; - Node *n1, nod, nod1; - - cursafe = 0; - curarg = 0; - maxargsafe = 0; - - /* - * isolate name - */ - for(n1 = nn;; n1 = n1->left) { - if(n1 == Z) { - diag(nn, "cant find function name"); - return; - } - if(n1->op == ONAME) - break; - } - nearln = nn->lineno; - gpseudo(ATEXT, n1->sym, nodconst(stkoff)); - - /* - * isolate first argument - */ - if(REGARG) { - if(typesuv[thisfn->link->etype]) { - nod1 = *nodret->left; - nodreg(&nod, &nod1, REGARG); - gmove(&nod, &nod1); - } else - if(firstarg && typechlp[firstargtype->etype]) { - nod1 = *nodret->left; - nod1.sym = firstarg; - nod1.type = firstargtype; - nod1.xoffset = align(0, firstargtype, Aarg1); - nod1.etype = firstargtype->etype; - nodreg(&nod, &nod1, REGARG); - gmove(&nod, &nod1); - } - } - - sp = p; - retok = 0; - gen(n); - if(!retok) - if(thisfn->link->etype != TVOID) - warn(Z, "no return at end of function: %s", n1->sym->name); - noretval(3); - if(thisfn && thisfn->link && typefd[thisfn->link->etype]) - gins(AFLDZ, Z, Z); - gbranch(ORETURN); - - if(!debug['N'] || debug['R'] || debug['P']) - regopt(sp); - sp->to.offset += maxargsafe; -} - -void -supgen(Node *n) -{ - long spc; - Prog *sp; - - if(n == Z) - return; - suppress++; - spc = pc; - sp = lastp; - gen(n); - lastp = sp; - pc = spc; - sp->link = nil; - suppress--; -} - -void -gen(Node *n) -{ - Node *l, nod; - Prog *sp, *spc, *spb; - Case *cn; - long sbc, scc; - int f, o; - -loop: - if(n == Z) - return; - nearln = n->lineno; - o = n->op; - if(debug['G']) - if(o != OLIST) - print("%L %O\n", nearln, o); - - retok = 0; - switch(o) { - - default: - complex(n); - cgen(n, Z); - break; - - case OLIST: - gen(n->left); - - rloop: - n = n->right; - goto loop; - - case ORETURN: - retok = 1; - complex(n); - if(n->type == T) - break; - l = n->left; - if(l == Z) { - noretval(3); - if(typefd[n->type->etype]) - gins(AFLDZ, Z, Z); - gbranch(ORETURN); - break; - } - if(typesuv[n->type->etype]) { - sugen(l, nodret, n->type->width); - noretval(3); - gbranch(ORETURN); - break; - } - regret(&nod, n); - cgen(l, &nod); - regfree(&nod); - if(typefd[n->type->etype]) - noretval(1); - else - noretval(2); - gbranch(ORETURN); - break; - - case OLABEL: - l = n->left; - if(l) { - l->xoffset = pc; - if(l->label) - patch(l->label, pc); - } - gbranch(OGOTO); /* prevent self reference in reg */ - patch(p, pc); - goto rloop; - - case OGOTO: - retok = 1; - n = n->left; - if(n == Z) - return; - if(n->complex == 0) { - diag(Z, "label undefined: %s", n->sym->name); - return; - } - if(suppress) - return; - gbranch(OGOTO); - if(n->xoffset) { - patch(p, n->xoffset); - return; - } - if(n->label) - patch(n->label, pc-1); - n->label = p; - return; - - case OCASE: - l = n->left; - if(cases == C) - diag(n, "case/default outside a switch"); - if(l == Z) { - casf(); - cases->val = 0; - cases->def = 1; - cases->label = pc; - goto rloop; - } - complex(l); - if(l->type == T) - goto rloop; - if(l->op == OCONST) - if(typechl[l->type->etype]) { - casf(); - cases->val = l->vconst; - cases->def = 0; - cases->label = pc; - goto rloop; - } - diag(n, "case expression must be integer constant"); - goto rloop; - - case OSWITCH: - l = n->left; - complex(l); - if(l->type == T) - break; - if(!typechl[l->type->etype]) { - diag(n, "switch expression must be integer"); - break; - } - - gbranch(OGOTO); /* entry */ - sp = p; - - cn = cases; - cases = C; - casf(); - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - gen(n->right); - gbranch(OGOTO); - patch(p, breakpc); - - patch(sp, pc); - regalloc(&nod, l, Z); - nod.type = types[TLONG]; - cgen(l, &nod); - doswit(&nod); - regfree(&nod); - patch(spb, pc); - - cases = cn; - breakpc = sbc; - break; - - case OWHILE: - case ODWHILE: - l = n->left; - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - if(n->op == OWHILE) - patch(sp, pc); - bcomplex(l, Z); /* test */ - patch(p, breakpc); - - if(n->op == ODWHILE) - patch(sp, pc); - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - break; - - case OFOR: - l = n->left; - gen(l->right->left); /* init */ - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - gen(l->right->right); /* inc */ - patch(sp, pc); - if(l->left != Z) { /* test */ - bcomplex(l->left, Z); - patch(p, breakpc); - } - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - break; - - case OCONTINUE: - if(continpc < 0) { - diag(n, "continue not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, continpc); - break; - - case OBREAK: - if(breakpc < 0) { - diag(n, "break not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, breakpc); - break; - - case OIF: - l = n->left; - if(bcomplex(l, n->right)) { - if(typefd[l->type->etype]) - f = !l->fconst; - else - f = !l->vconst; - if(debug['c']) - print("%L const if %s\n", nearln, f ? "false" : "true"); - if(f) { - supgen(n->right->left); - gen(n->right->right); - } - else { - gen(n->right->left); - supgen(n->right->right); - } - } - else { - sp = p; - if(n->right->left != Z) - gen(n->right->left); - if(n->right->right != Z) { - gbranch(OGOTO); - patch(sp, pc); - sp = p; - gen(n->right->right); - } - patch(sp, pc); - } - break; - - case OSET: - case OUSED: - usedset(n->left, o); - break; - } -} - -void -usedset(Node *n, int o) -{ - if(n->op == OLIST) { - usedset(n->left, o); - usedset(n->right, o); - return; - } - complex(n); - switch(n->op) { - case OADDR: /* volatile */ - gins(ANOP, n, Z); - break; - case ONAME: - if(o == OSET) - gins(ANOP, Z, n); - else - gins(ANOP, n, Z); - break; - } -} - -void noretval(int n) { @@ -391,6 +12,9 @@ noretval(int n) gins(ANOP, Z, Z); p->to.type = FREGRET; } + if((n&3) == 3) + if(thisfn && thisfn->link && typefd[thisfn->link->etype]) + gins(AFLDZ, Z, Z); } /* welcome to commute */ @@ -810,33 +434,3 @@ indx(Node *n) prtree(idx.basetree, "base"); } } - -int -bcomplex(Node *n, Node *c) -{ - Node *b, nod; - - complex(n); - if(n->type != T) - if(tcompat(n, T, n->type, tnot)) - n->type = T; - if(n->type != T) { - if(c != Z && n->op == OCONST && deadheads(c)) - return 1; - if(typev[n->type->etype] && machcap(Z)) { - b = &nod; - b->op = ONE; - b->left = n; - b->right = new(0, Z, Z); - *b->right = *nodconst(0); - b->right->type = n->type; - b->type = types[TLONG]; - cgen64(b, Z); - return 0; - } - bool64(n); - boolgen(n, 1, Z); - } else - gbranch(OGOTO); - return 0; -} diff --git a/utils/8c/swt.c b/utils/8c/swt.c index a29b95c7..46fd71eb 100644 --- a/utils/8c/swt.c +++ b/utils/8c/swt.c @@ -1,57 +1,5 @@ #include "gc.h" -int -swcmp(const void *a1, const void *a2) -{ - C1 *p1, *p2; - - p1 = (C1*)a1; - p2 = (C1*)a2; - if(p1->val < p2->val) - return -1; - return p1->val > p2->val; -} - -void -doswit(Node *n) -{ - Case *c; - C1 *q, *iq; - long def, nc, i; - - def = 0; - nc = 0; - for(c = cases; c->link != C; c = c->link) { - if(c->def) { - if(def) - diag(n, "more than one default in switch"); - def = c->label; - continue; - } - nc++; - } - - iq = alloc(nc*sizeof(C1)); - q = iq; - for(c = cases; c->link != C; c = c->link) { - if(c->def) - continue; - q->label = c->label; - q->val = c->val; - q++; - } - qsort(iq, nc, sizeof(C1), swcmp); - if(debug['W']) - for(i=0; i<nc; i++) - print("case %2ld: = %.8lux\n", i, iq[i].val); - if(def == 0) - def = breakpc; - for(i=0; i<nc-1; i++) - if(iq[i].val == iq[i+1].val) - diag(n, "duplicate cases in switch %ld", iq[i].val); - swit1(iq, nc, def, n); -} - void swit1(C1 *q, int nc, long def, Node *n) { @@ -89,16 +37,6 @@ swit1(C1 *q, int nc, long def, Node *n) } void -casf(void) -{ - Case *c; - - c = alloc(sizeof(*c)); - c->link = cases; - cases = c; -} - -void bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) { int sh; @@ -189,43 +127,6 @@ outstring(char *s, long n) return r; } -long -outlstring(ushort *s, long n) -{ - char buf[2]; - int c; - long r; - - if(suppress) - return nstring; - while(nstring & 1) - outstring("", 1); - r = nstring; - while(n > 0) { - c = *s++; - if(align(0, types[TCHAR], Aarg1)) { - buf[0] = c>>8; - buf[1] = c; - } else { - buf[0] = c; - buf[1] = c>>8; - } - outstring(buf, 2); - n -= sizeof(ushort); - } - return r; -} - -void -nullwarn(Node *l, Node *r) -{ - warn(Z, "result of operation not used"); - if(l != Z) - cgen(l, Z); - if(r != Z) - cgen(r, Z); -} - void sextern(Sym *s, Node *a, long o, long w) { @@ -542,35 +443,6 @@ zaddr(Biobuf *b, Adr *a, int s) Bputc(b, a->type); } -void -ieeedtod(Ieee *ieee, double native) -{ - double fr, ho, f; - int exp; - - if(native < 0) { - ieeedtod(ieee, -native); - ieee->h |= 0x80000000L; - return; - } - if(native == 0) { - ieee->l = 0; - ieee->h = 0; - return; - } - fr = frexp(native, &exp); - f = 2097152L; /* shouldnt use fp constants here */ - fr = modf(fr*f, &ho); - ieee->h = ho; - ieee->h &= 0xfffffL; - ieee->h |= (exp+1022L) << 20; - f = 65536L; - fr = modf(fr*f, &ho); - ieee->l = ho; - ieee->l <<= 16; - ieee->l |= (long)(fr*f); -} - long align(long i, Type *t, int op) { diff --git a/utils/8c/txt.c b/utils/8c/txt.c index 841116ab..44413d81 100644 --- a/utils/8c/txt.c +++ b/utils/8c/txt.c @@ -203,7 +203,7 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) sugen(n, tn2, n->type->width); return; } - if(REGARG && curarg == 0 && typeilp[n->type->etype]) { + if(REGARG>=0 && curarg == 0 && typeilp[n->type->etype]) { regaalloc1(tn1, n); if(n->complex >= FNX) { cgen(*fnxp, tn1); @@ -306,6 +306,7 @@ regalloc(Node *n, Node *tn, Node *o) if(reg[i] == 0) goto out; diag(tn, "out of fixed registers"); +abort(); goto err; case TFLOAT: @@ -321,6 +322,7 @@ out: if(i) reg[i]++; nodreg(n, tn, i); +//print("+ %R %d\n", i, reg[i]); } void @@ -347,6 +349,7 @@ regfree(Node *n) if(reg[i] <= 0) goto err; reg[i]--; +//print("- %R %d\n", i, reg[i]); return; err: diag(n, "error in regfree: %R", i); @@ -367,11 +370,19 @@ regsalloc(Node *n, Node *nn) void regaalloc1(Node *n, Node *nn) { + USED(nn); + + if(REGARG < 0) { + diag(n, "regaalloc1"); + return; + } +/* not reached nodreg(n, nn, REGARG); reg[REGARG]++; curarg = align(curarg, nn->type, Aarg1); curarg = align(curarg, nn->type, Aarg2); maxargsafe = maxround(maxargsafe, cursafe+curarg); +*/ } void @@ -412,6 +423,7 @@ naddr(Node *n, Adr *a) default: bad: diag(n, "bad in naddr: %O %D", n->op, a); +//prtree(n, "naddr"); break; case OREGISTER: @@ -787,9 +799,7 @@ gmove(Node *f, Node *t) case CASE( TFLOAT, TSHORT): case CASE( TFLOAT, TUSHORT): case CASE( TFLOAT, TINT): - case CASE( TFLOAT, TUINT): case CASE( TFLOAT, TLONG): - case CASE( TFLOAT, TULONG): case CASE( TFLOAT, TIND): case CASE( TDOUBLE,TCHAR): @@ -797,20 +807,8 @@ gmove(Node *f, Node *t) case CASE( TDOUBLE,TSHORT): case CASE( TDOUBLE,TUSHORT): case CASE( TDOUBLE,TINT): - case CASE( TDOUBLE,TUINT): case CASE( TDOUBLE,TLONG): - case CASE( TDOUBLE,TULONG): case CASE( TDOUBLE,TIND): - - case CASE( TVLONG, TCHAR): - case CASE( TVLONG, TUCHAR): - case CASE( TVLONG, TSHORT): - case CASE( TVLONG, TUSHORT): - case CASE( TVLONG, TINT): - case CASE( TVLONG, TUINT): - case CASE( TVLONG, TLONG): - case CASE( TVLONG, TULONG): - case CASE( TVLONG, TIND): if(fproundflg) { regsalloc(&nod, ®node); gins(AFMOVLP, f, &nod); @@ -830,13 +828,26 @@ gmove(Node *f, Node *t) return; /* + * float to ulong + */ + case CASE( TDOUBLE, TULONG): + case CASE( TFLOAT, TULONG): + case CASE( TDOUBLE, TUINT): + case CASE( TFLOAT, TUINT): + regsalloc(&nod, ®node); + gmove(f, &fregnode0); + gins(AFADDD, nodfconst(-2147483648.), &fregnode0); + gins(AFMOVLP, f, &nod); + gins(ASUBL, nodconst(-2147483648), &nod); + gmove(&nod, t); + return; + +/* * ulong to float */ case CASE( TULONG, TDOUBLE): - case CASE( TULONG, TVLONG): case CASE( TULONG, TFLOAT): case CASE( TUINT, TDOUBLE): - case CASE( TUINT, TVLONG): case CASE( TUINT, TFLOAT): regalloc(&nod, f, f); gmove(f, &nod); @@ -869,14 +880,6 @@ gmove(Node *f, Node *t) case CASE( TINT, TDOUBLE): case CASE( TLONG, TDOUBLE): case CASE( TIND, TDOUBLE): - - case CASE( TCHAR, TVLONG): - case CASE( TUCHAR, TVLONG): - case CASE( TSHORT, TVLONG): - case CASE( TUSHORT,TVLONG): - case CASE( TINT, TVLONG): - case CASE( TLONG, TVLONG): - case CASE( TIND, TVLONG): regsalloc(&nod, ®node); gmove(f, &nod); gins(AFMOVL, &nod, &fregnode0); @@ -887,15 +890,9 @@ gmove(Node *f, Node *t) */ case CASE( TFLOAT, TFLOAT): case CASE( TDOUBLE,TFLOAT): - case CASE( TVLONG, TFLOAT): case CASE( TFLOAT, TDOUBLE): case CASE( TDOUBLE,TDOUBLE): - case CASE( TVLONG, TDOUBLE): - - case CASE( TFLOAT, TVLONG): - case CASE( TDOUBLE,TVLONG): - case CASE( TVLONG, TVLONG): a = AFMOVD; break; } if(a == AMOVL || a == AFMOVD) @@ -923,6 +920,7 @@ print("botch in doindex\n"); if(n->left->op == OCONST) idx.ptr = D_CONST; else if(n->left->op == OREGISTER) +// else if(n->left->op == OREGISTER && typeil[n->left->type->etype]) idx.ptr = n->left->reg; else if(n->left->op != OADDR) { reg[D_BP]++; // cant be used as a base diff --git a/utils/8l/asm.c b/utils/8l/asm.c index 56eee141..a1bb36ba 100644 --- a/utils/8l/asm.c +++ b/utils/8l/asm.c @@ -2,6 +2,8 @@ #define Dbufslop 100 +#define PADDR(a) ((ulong)(a) & ~0xF0000000) + long entryvalue(void) { @@ -27,20 +29,51 @@ entryvalue(void) } void -wput(ushort w) +wputl(ushort w) { cput(w); cput(w>>8); } void -wputb(ushort w) +wput(ushort w) { cput(w>>8); cput(w); } void +lput(long l) +{ + cput(l>>24); + cput(l>>16); + cput(l>>8); + cput(l); +} + +void +lputl(long l) +{ + cput(l); + cput(l>>8); + cput(l>>16); + cput(l>>24); +} + +void +strnput(char *s, int n) +{ + for(; *s && n > 0; s++){ + cput(*s); + n--; + } + while(n > 0){ + cput(0); + n--; + } +} + +void asmb(void) { Prog *p; @@ -89,7 +122,7 @@ asmb(void) cflush(); switch(HEADTYPE) { default: - diag("unknown header type %d", HEADTYPE); + diag("unknown header type %ld", HEADTYPE); case 0: seek(cout, rnd(HEADR+textsize, 8192), 0); break; @@ -98,6 +131,7 @@ asmb(void) seek(cout, textsize+HEADR, 0); break; case 2: + case 5: seek(cout, HEADR+textsize, 0); break; case 3: @@ -140,6 +174,7 @@ asmb(void) seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); break; case 2: + case 5: seek(cout, HEADR+textsize+datsize, 0); break; case 3: @@ -179,7 +214,7 @@ asmb(void) lput(symsize); /* nsyms */ lput((0x38L<<16)|7L); /* size of optional hdr and flags */ lput((0413<<16)|0437L); /* magic and version */ - lput(rnd(HEADR+textsize, 4096)); /* sizes */ + lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ @@ -193,7 +228,6 @@ asmb(void) lput(0L); lput(~0L); /* gp value ?? */ break; - lputl(0); /* x */ case 1: /* unix coff */ /* * file header @@ -216,7 +250,7 @@ asmb(void) /* * text section header */ - s8put(".text"); + strnput(".text", 8); lputl(HEADR); /* pa */ lputl(HEADR); /* va */ lputl(textsize); /* text size */ @@ -228,7 +262,7 @@ asmb(void) /* * data section header */ - s8put(".data"); + strnput(".data", 8); lputl(INITDAT); /* pa */ lputl(INITDAT); /* va */ lputl(datsize); /* data size */ @@ -240,7 +274,7 @@ asmb(void) /* * bss section header */ - s8put(".bss"); + strnput(".bss", 8); lputl(INITDAT+datsize); /* pa */ lputl(INITDAT+datsize); /* va */ lputl(bsssize); /* bss size */ @@ -252,7 +286,7 @@ asmb(void) /* * comment section header */ - s8put(".comment"); + strnput(".comment", 8); lputl(0); /* pa */ lputl(0); /* va */ lputl(symsize+lcsize); /* comment size */ @@ -266,7 +300,7 @@ asmb(void) magic = 4*11*11+7; if(dlm) magic |= 0x80000000; - lput(magic); /* magic */ + lput(magic); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); @@ -281,56 +315,74 @@ asmb(void) case 4: /* fake MS-DOS .EXE */ v = rnd(HEADR+textsize, INITRND)+datsize; - wput(0x5A4D); /* 'MZ' */ - wput(v % 512); /* bytes in last page */ - wput(rnd(v, 512)/512); /* total number of pages */ - wput(0x0000); /* number of reloc items */ + wputl(0x5A4D); /* 'MZ' */ + wputl(v % 512); /* bytes in last page */ + wputl(rnd(v, 512)/512); /* total number of pages */ + wputl(0x0000); /* number of reloc items */ v = rnd(HEADR-(INITTEXT & 0xFFFF), 16); - wput(v/16); /* size of header */ - wput(0x0000); /* minimum allocation */ - wput(0xFFFF); /* maximum allocation */ - wput(0x0000); /* initial ss value */ - wput(0x0100); /* initial sp value */ - wput(0x0000); /* complemented checksum */ + wputl(v/16); /* size of header */ + wputl(0x0000); /* minimum allocation */ + wputl(0xFFFF); /* maximum allocation */ + wputl(0x0000); /* initial ss value */ + wputl(0x0100); /* initial sp value */ + wputl(0x0000); /* complemented checksum */ v = entryvalue(); - wput(v); /* initial ip value (!) */ - wput(0x0000); /* initial cs value */ - wput(0x0000); - wput(0x0000); - wput(0x003E); /* reloc table offset */ - wput(0x0000); /* overlay number */ + wputl(v); /* initial ip value (!) */ + wputl(0x0000); /* initial cs value */ + wputl(0x0000); + wputl(0x0000); + wputl(0x003E); /* reloc table offset */ + wputl(0x0000); /* overlay number */ break; - } - cflush(); -} - -void -lput(long l) -{ - cput(l>>24); - cput(l>>16); - cput(l>>8); - cput(l); -} + case 5: + strnput("\177ELF", 4); /* e_ident */ + cput(1); /* class = 32 bit */ + cput(1); /* data = LSB */ + cput(1); /* version = CURRENT */ + strnput("", 9); + wputl(2); /* type = EXEC */ + wputl(3); /* machine = 386 */ + lputl(1L); /* version = CURRENT */ + lputl(PADDR(entryvalue())); /* entry vaddr */ + lputl(52L); /* offset to first phdr */ + lputl(0L); /* offset to first shdr */ + lputl(0L); /* flags = 386 */ + wputl(52); /* Ehdr size */ + wputl(32); /* Phdr size */ + wputl(3); /* # of Phdrs */ + wputl(0); /* Shdr size */ + wputl(0); /* # of Shdrs */ + wputl(0); /* Shdr string size */ -void -lputl(long l) -{ - cput(l); - cput(l>>8); - cput(l>>16); - cput(l>>24); -} + lputl(1L); /* text - type = PT_LOAD */ + lputl(HEADR); /* file offset */ + lputl(INITTEXT); /* vaddr */ + lputl(PADDR(INITTEXT)); /* paddr */ + lputl(textsize); /* file size */ + lputl(textsize); /* memory size */ + lputl(0x05L); /* protections = RX */ + lputl(INITRND); /* alignment */ -void -s8put(char *n) -{ - char name[8]; - int i; + lputl(1L); /* data - type = PT_LOAD */ + lputl(HEADR+textsize); /* file offset */ + lputl(INITDAT); /* vaddr */ + lputl(PADDR(INITDAT)); /* paddr */ + lputl(datsize); /* file size */ + lputl(datsize+bsssize); /* memory size */ + lputl(0x06L); /* protections = RW */ + lputl(INITRND); /* alignment */ - strncpy(name, n, sizeof(name)); - for(i=0; i<sizeof(name); i++) - cput(name[i]); + lputl(0L); /* data - type = PT_NULL */ + lputl(HEADR+textsize+datsize); /* file offset */ + lputl(0L); + lputl(0L); + lputl(symsize); /* symbol table size */ + lputl(lcsize); /* line number size */ + lputl(0x04L); /* protections = R */ + lputl(0x04L); /* alignment */ + break; + } + cflush(); } void diff --git a/utils/8l/l.h b/utils/8l/l.h index 5c274418..3affb6ae 100644 --- a/utils/8l/l.h +++ b/utils/8l/l.h @@ -9,6 +9,7 @@ #define P ((Prog*)0) #define S ((Sym*)0) #define TNAME (curtext?curtext->from.sym->name:noname) + #define cput(c)\ { *cbp++ = c;\ if(--cbc <= 0)\ @@ -246,7 +247,6 @@ EXTERN uchar and[30]; EXTERN char reg[D_NONE]; EXTERN Prog* lastp; EXTERN long lcsize; -EXTERN int maxop; EXTERN int nerrors; EXTERN long nhunk; EXTERN long nsymbol; @@ -266,7 +266,7 @@ EXTERN int dtype; EXTERN Adr* reloca; EXTERN int doexp, dlm; EXTERN int imports, nimports; -EXTERN int exports, nexports; +EXTERN int exports, nexports, allexport; EXTERN char* EXPTAB; EXTERN Prog undefp; @@ -332,12 +332,11 @@ void readundefs(char*, int); int relinv(int); long reuse(Prog*, Sym*); long rnd(long, long); -void s8put(char*); void span(void); void undef(void); void undefsym(Sym*); long vaddr(Adr*); -void wputb(ushort); +void wput(ushort); void xdefine(char*, int, long); void xfol(Prog*); int zaddr(uchar*, Adr*, Sym*[]); diff --git a/utils/8l/list.c b/utils/8l/list.c index 7fea4cb9..f52477d5 100644 --- a/utils/8l/list.c +++ b/utils/8l/list.c @@ -285,7 +285,7 @@ diag(char *fmt, ...) print("%s: %s\n", tn, buf); nerrors++; - if(nerrors > 20) { + if(nerrors > 20 && !debug['A']) { print("too many errors\n"); errorexit(); } diff --git a/utils/8l/obj.c b/utils/8l/obj.c index 07e5c53f..a2cd7c9a 100644 --- a/utils/8l/obj.c +++ b/utils/8l/obj.c @@ -17,6 +17,7 @@ char *thestring = "386"; * -H2 -T4128 -R4096 is plan9 format * -H3 -Tx -Rx is MS-DOS .COM * -H4 -Tx -Rx is fake MS-DOS .EXE + * -H5 -T0x80100020 -R4096 is ELF */ static int @@ -94,8 +95,13 @@ main(int argc, char *argv[]) break; case 'x': /* produce export table */ doexp = 1; - if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) - readundefs(ARGF(), SEXPORT); + if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])){ + a = ARGF(); + if(strcmp(a, "*") == 0) + allexport = 1; + else + readundefs(a, SEXPORT); + } break; case 'u': /* produce dynamically loadable module */ dlm = 1; @@ -172,6 +178,15 @@ main(int argc, char *argv[]) if(debug['v']) Bprint(&bso, "HEADR = 0x%ld\n", HEADR); break; + case 5: /* elf executable */ + HEADR = rnd(52L+3*32L, 16); + if(INITTEXT == -1) + INITTEXT = 0x80100020L; + 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", @@ -185,7 +200,6 @@ main(int argc, char *argv[]) diag("phase error in optab: %d", i); errorexit(); } - maxop = i; for(i=0; i<Ymax; i++) ycover[i*Ymax + i] = 1; diff --git a/utils/8l/pass.c b/utils/8l/pass.c index 9f54d614..0e0ec346 100644 --- a/utils/8l/pass.c +++ b/utils/8l/pass.c @@ -629,7 +629,8 @@ import(void) if(s->value != 0) diag("value != 0 on SXREF"); undefsym(s); - Bprint(&bso, "IMPORT: %s sig=%lux v=%ld\n", s->name, s->sig, s->value); + if(debug['X']) + Bprint(&bso, "IMPORT: %s sig=%lux v=%ld\n", s->name, s->sig, s->value); if(debug['S']) s->sig = 0; } @@ -674,14 +675,14 @@ export(void) n = 0; for(i = 0; i < NHASH; i++) for(s = hash[i]; s != S; s = s->link) - if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport)) n++; esyms = malloc(n*sizeof(Sym*)); ne = n; n = 0; for(i = 0; i < NHASH; i++) for(s = hash[i]; s != S; s = s->link) - if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT)) + if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport)) esyms[n++] = s; for(i = 0; i < ne-1; i++) for(j = i+1; j < ne; j++) diff --git a/utils/8l/span.c b/utils/8l/span.c index ef135474..0adecbb7 100644 --- a/utils/8l/span.c +++ b/utils/8l/span.c @@ -1133,7 +1133,7 @@ bad: } return; } - diag("doasm: notfound t2=%lux from=%lux to=%lux %P", t[2], p->from.type, p->to.type, p); + diag("doasm: notfound t2=%ux from=%ux to=%ux %P", t[2], p->from.type, p->to.type, p); return; mfound: @@ -1366,7 +1366,7 @@ asmdyn() t++; } else if(c == 1){ - wputb(ra); + wput(ra); t += 2; } else{ diff --git a/utils/kl/span.c b/utils/kl/span.c index fdfb8034..a788b8d3 100644 --- a/utils/kl/span.c +++ b/utils/kl/span.c @@ -182,6 +182,7 @@ aclass(Adr *a) instoffset = s->value + a->offset + INITDAT; /* not sure why this barfs */ return C_LCON; +/* if(instoffset == 0) return C_ZCON; if(instoffset >= -0x1000 && instoffset <= 0xfff) @@ -189,6 +190,7 @@ return C_LCON; if((instoffset & 0x3ff) == 0) return C_UCON; return C_LCON; +*/ case D_AUTO: instoffset = autosize + a->offset; |
