# HG changeset patch # User David du Colombier <0intro@gmail.com> # Date 1331041372 -3600 # Node ID 4c0cd44c79c3305dd5af1e25732f048ad068ca7b # Parent e88fc68069f4892d419ac741cafa33df8b46f2a7 5l, 6l, 8a, 8c, 8l, cc: sync with plan 9 R=charles.forsyth, nixiedev CC=nix-dev http://codereview.appspot.com/5690070 Committer: Francisco J Ballesteros diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/5l/asm.c --- a/sys/src/cmd/5l/asm.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/5l/asm.c Tue Mar 06 14:42:52 2012 +0100 @@ -84,6 +84,7 @@ seek(cout, OFFSET, 0); break; case 3: + case 6: /* no header, padded segments */ OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; @@ -119,6 +120,7 @@ seek(cout, OFFSET, 0); break; case 3: + case 6: /* no header, padded segments */ OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; @@ -147,6 +149,7 @@ seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ + case 6: /* no header, padded segments */ break; case 1: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/5l/obj.c --- a/sys/src/cmd/5l/obj.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/5l/obj.c Tue Mar 06 14:42:52 2012 +0100 @@ -12,11 +12,13 @@ char *thestring = "arm"; /* + * -H0 no header * -H1 -T0x10005000 -R4 is aif for risc os * -H2 -T4128 -R4096 is plan9 format * -H3 -T0xF0000020 -R4 is NetBSD format * -H4 is IXP1200 (raw) * -H5 -T0xC0008010 -R1024 is ipaq + * -H6 -R4096 no header with segments padded to pages */ static int @@ -127,6 +129,7 @@ diag("unknown -H option"); errorexit(); case 0: /* no header */ + case 6: /* no header, padded segments */ HEADR = 0L; if(INITTEXT == -1) INITTEXT = 0; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/6l/optab.c --- a/sys/src/cmd/6l/optab.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/6l/optab.c Tue Mar 06 14:42:52 2012 +0100 @@ -753,7 +753,7 @@ { AMOVBWSX, ymb_rl, Pq, 0xbe }, { AMOVBWZX, ymb_rl, Pq, 0xb6 }, { AMOVO, yxmov, Pe, 0x6f,0x7f }, - { AMOVOU, yxmov, Pf2, 0x6f,0x7f }, + { AMOVOU, yxmov, Pf3, 0x6f,0x7f }, { AMOVHLPS, yxr, Pm, 0x12 }, { AMOVHPD, yxmov, Pe, 0x16,0x17 }, { AMOVHPS, yxmov, Pm, 0x16,0x17 }, @@ -877,9 +877,9 @@ { APOPQ, ypopl, Py, 0x58,0x8f,(00) }, { APOPW, ypopl, Pe, 0x58,0x8f,(00) }, { APOR, ymm, Py, 0xeb,Pe,0xeb }, - { APSADBW, yxm, Pw, Pe,0xf6 }, + { APSADBW, yxm, Pq, 0xf6 }, { APSHUFHW, yxshuf, Pf3, 0x70 }, - { APSHUFL, yxm, Pw, Pe,0x70 }, + { APSHUFL, yxshuf, Pq, 0x70 }, { APSHUFLW, yxshuf, Pf2, 0x70 }, { APSHUFW, ymshuf, Pm, 0x70 }, { APSLLO, ypsdq, Pq, 0x73,(07) }, diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/6l/span.c --- a/sys/src/cmd/6l/span.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/6l/span.c Tue Mar 06 14:42:52 2012 +0100 @@ -1574,7 +1574,7 @@ /* * as befits the whole approach of the architecture, * the rex prefix must appear before the first opcode byte - * (and thus after any 66/67/f2/f3 prefix bytes, but + * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but * before the 0f opcode escape!), or it might be ignored. * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'. */ @@ -1583,7 +1583,7 @@ n = andptr - and; for(np = 0; np < n; np++) { c = and[np]; - if(c != 0x66 && c != 0xf2 && c != 0xf3 && c != 0x67) + if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26) break; } memmove(and+np+1, and+np, n-np); diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8a/a.h --- a/sys/src/cmd/8a/a.h Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8a/a.h Tue Mar 06 14:42:52 2012 +0100 @@ -72,6 +72,7 @@ double dval; char sval[8]; long offset; + long offset2; Sym* sym; short type; short index; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8a/a.y --- a/sys/src/cmd/8a/a.y Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8a/a.y Tue Mar 06 14:42:52 2012 +0100 @@ -4,6 +4,10 @@ %union { Sym *sym; long lval; + struct { + long v1; + long v2; + } con2; double dval; char sval[8]; Gen gen; @@ -16,16 +20,17 @@ %left '+' '-' %left '*' '/' '%' %token LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 -%token LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI +%token LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG %token LCONST LFP LPC LSB %token LBREG LLREG LSREG LFREG %token LFCONST %token LSCONST LSP %token LNAME LLAB LVAR %type con expr pointer offset -%type mem imm reg nam rel rem rim rom omem nmem +%type con2 +%type mem imm imm2 reg nam rel rem rim rom omem nmem %type nonnon nonrel nonrem rimnon rimrem remrim -%type spec1 spec2 spec3 spec4 spec5 spec6 spec7 +%type spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 %% prog: | prog line @@ -73,6 +78,7 @@ | LTYPES spec5 { outcode($1, &$2); } | LTYPEM spec6 { outcode($1, &$2); } | LTYPEI spec7 { outcode($1, &$2); } +| LTYPEG spec8 { outcode($1, &$2); } nonnon: { @@ -219,6 +225,19 @@ $$.to = $3; } +spec8: /* GLOBL */ + mem ',' imm + { + $$.from = $1; + $$.to = $3; + } +| mem ',' con ',' imm + { + $$.from = $1; + $$.from.scale = $3; + $$.to = $5; + } + rem: reg | mem @@ -236,6 +255,7 @@ } | reg | omem +| imm rim: rem @@ -335,6 +355,37 @@ $$.dval = -$3; } +imm2: + '$' con2 + { + $$ = nullgen; + $$.type = D_CONST2; + $$.offset = $2.v1; + $$.offset2 = $2.v2; + } + +con2: + LCONST + { + $$.v1 = $1; + $$.v2 = 0; + } +| '-' LCONST + { + $$.v1 = -$2; + $$.v2 = 0; + } +| LCONST '-' LCONST + { + $$.v1 = $1; + $$.v2 = $3; + } +| '-' LCONST '-' LCONST + { + $$.v1 = -$2; + $$.v2 = $4; + } + mem: omem | nmem @@ -386,6 +437,12 @@ $$ = nullgen; $$.type = D_INDIR+D_SP; } +| con '(' LSREG ')' + { + $$ = nullgen; + $$.type = D_INDIR+$3; + $$.offset = $1; + } | '(' LLREG '*' con ')' { $$ = nullgen; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8a/l.s --- a/sys/src/cmd/8a/l.s Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8a/l.s Tue Mar 06 14:42:52 2012 +0100 @@ -221,7 +221,7 @@ * 16 meg of physical memory */ LEAL tpt-KZERO(SB),AX /* get phys addr of temporary page table */ - ADDL $(BY2PG-1),AX /* must be page alligned */ + ADDL $(BY2PG-1),AX /* must be page aligned */ ANDL $(~(BY2PG-1)),AX /* ... */ MOVL $(4*1024),CX /* pte's per page */ MOVL $((((4*1024)-1)<>16); Bputc(&obuf, l>>24); } + if(t & T_OFFSET2) { + l = a->offset2; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + } if(t & T_SYM) /* implies sym */ Bputc(&obuf, s); if(t & T_FCONST) { diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/bound.c --- a/sys/src/cmd/8c/bound.c Fri Mar 02 10:40:01 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1117 +0,0 @@ -#include "gc.h" -#include "bound.h" - -static BB* bbfree; -static BBset* bbsfree; -static int bballoc; -static int bbsalloc; -static BB bbz; -static BBset bbsz; -static BB* firstbb; -static BB* lastbb; -static BB* wounded; -static BB* bbaux; -static BBset* recalc; -static BBset* bbhash[BBHASH]; -static BB** ordered; -static int bcount; -static BBset** heap; -static int heapn; -static int bsize; -static char bbbuff[BBBSIZE]; -static int bchange; - -#define bdebug (debug['v']) -#define dbg 0 -#define bcheck 0 - -static long -Rn(Reg *r) -{ - if(r == R) - return -1; - return r->rpo; -} - -static BB* -bba(void) -{ - BB *b; - - bballoc++; - b = bbfree; - if(b == nil) { - b = alloc(sizeof(*b)); - } else - bbfree = b->link; - - *b = bbz; - return b; -} - -static void -bfree(BB *b) -{ - bballoc--; - b->link = bbfree; - bbfree = b; -} - -static BBset* -bbsa(void) -{ - BBset *b; - - bballoc++; - b = bbsfree; - if(b == nil) { - b = alloc(sizeof(*b)); - } else - bbsfree = b->link; - - *b = bbsz; - return b; -} - -static void -bsfree(BBset *b) -{ - bballoc--; - b->link = bbsfree; - bbsfree = b; -} - -static void -dumpheap(void) -{ - int i; - - for(i = 1; i <= heapn; i++) - print(" %d", heap[i]->damage); -} - -static void -checkheap(void) -{ - int N, N2, n, c; - - N = heapn; - N2 = N >> 1; - for(n = 1; n <= N2; n++) { - c = n << 1; - if((heap[c]->damage > heap[n]->damage) - || ((c < N) && (heap[c + 1]->damage > heap[n]->damage))) { - print("bad heap (%d:%d) %d [", n, heap[n]->damage, heapn); - dumpheap(); - print(" ]\n"); - abort(); - } - } -} - -static void -downheap(int n) -{ - int N, N2, d, c; - BBset *s, *t, *u; - - s = heap[n]; - d = s->damage; -//print("down %d %d", n, d); - N = heapn; - N2 = N >> 1; - while(n <= N2) { - c = n << 1; - t = heap[c]; - if(c < N) { - u = heap[c + 1]; - if(t->damage < u->damage) { - t = u; - c++; - } - } -//print(" [%d %d]", c, t->damage); - if(t->damage < d) - break; - heap[n] = t; - t->index = n; - n = c; - } - heap[n] = s; - s->index = n; -//print("\n"); -//checkheap(); -} - -static void -upheap(int n) -{ - int f, d; - BBset *s, *t; - - s = heap[n]; - d = s->damage; -//print("up %d %d", n, d); - while(n > 1) { - f = n >> 1; - t = heap[f]; -//print(" [%d %d]", f, t->damage); - if(t->damage >= d) - break; - heap[n] = t; - t->index = n; - n = f; - } - heap[n] = s; - s->index = n; -//print("\n"); -//checkheap(); -} - -static void -heapremove(BBset *s) -{ - int x; - BBset *t; - - x = s->index; - s->index = 0; - if(x == 0) - return; - if(x == heapn) { - heapn--; - return; - } - t = heap[heapn--]; - heap[x] = t; - t->index = x; - if(s->damage < t->damage) - upheap(x); - else - downheap(x); -} - -static void -heapadd(BBset *s) -{ - int n; - - n = heapn + 1; - heap[n] = s; - s->index = n; - heapn = n; - upheap(n); - -} - -static void -bbsrecalc(BBset *s) -{ - if(s->recalc) - return; - s->recalc = 1; - s->link = recalc; - recalc = s; - heapremove(s); -} - -static void -bbadd(BB *b, Hval h) -{ - int k; - BBset *s; - - k = h[0] & BBMASK; - for(s = bbhash[k]; s != nil; s = s->next) { - if(BBEQ(s->hash, h)) { - b->set = s; - b->link = s->ents; - s->ents = b; - bbsrecalc(s); - return; - } - } - s = bbsa(); - s->next = bbhash[k]; - bbhash[k] = s; - b->set = s; - b->link = nil; - s->ents = b; - BBCP(s->hash, h); - bbsrecalc(s); -} - -static int -hashbb(BB *b, Hval h) -{ - Reg *r; - Prog *p; - char *s; - int c, f, i, n; - - r = b->first; - s = bbbuff; - i = 0; - n = BBBSIZE; - for(;;) { - p = r->prog; - if(p->as != ANOP) { - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->rpo; - c = snprint(s, n, "%P", p); - s += c; - n -= c; - i++; - } - if(r == b->last) - break; - r = r->link; - } - if(n == 0) - return Bbig; - b->len = i; - BBMKHASH(bbbuff, BBBSIZE - n, h); - f = b->flags; - if(i == 1 && r->prog->as == AJMP && b->first->p1 == R) - f = Bjo; - else if(b->first->p1 != R) - f |= Bpre; - if(bdebug) - print("A %x %s %ux %ux\n", f, bbbuff, h[0], h[1]); - return f; -} - -static void -enterbb(BB *b) -{ - Hval h; - - b->flags = hashbb(b, h); - if(b->flags != Bbig) - bbadd(b, h); -} - -static void -preproc(BB *b, int x) -{ - BB *n; - Reg *r; - - ordered[x] = b; - if(b->last->rpo - b->first->rpo > BBBIG) { - b->flags = Bbig; - return; - } - if(b->first->p2 == nil) { - b->flags = Bdel; - return; - } - switch(b->last->prog->as) { - case ARET: - case AJMP: - case AIRETL: - break; - - default: - b->flags = Bdel; - n = bba(); - n->first = b->first; - for(r = b->last->link; r != R; r = r->link) { - switch(r->prog->as) { - case ARET: - case AJMP: - case AIRETL: - n->last = r; - n->flags = Bpin; - enterbb(n); - if(n->flags & Bpin) { - n->aux = bbaux; - bbaux = n; - } - else - bfree(n); - return; - } - } - bfree(n); - return; - } - enterbb(b); -} - -static int -p2len(Reg *r) -{ - int c; - - c = 0; - for(r = r->p2; r != nil; r = r->p2link) - c++; - return c; -} - -static void -calcdamage(BBset *s) -{ - BB *f; - int d, t; - - s->recalc = 0; - f = s->ents; - if(f == nil) - return; - if(f->flags & Bjo) { - if(bdebug) - print("add %ld jo\n", f->first->rpo); - s->damage = COSTJO; - heapadd(s); - return; - } - if(f->link == nil) { - if(bdebug) - print("solo %x %x\n", s->hash[0], s->hash[1]); - return; - } - - d = 0; - t = 0; - while(f != nil) { - if((f->flags & (Bpre|Bpin)) == 0 && f->last->link != R) { - t = 1; - d += (f->last->rpo - f->first->rpo) >> 1; - } - d += p2len(f->first); - f = f->link; - } - - if(t == 0) { - if(bdebug) - print("all pre %ld\n", s->ents->first->rpo); - return; - } - - if(bdebug) - print("add %ld %d\n", s->ents->first->rpo, d); - if(d > COSTHI) - d = COSTHI; - s->damage = d; - heapadd(s); -} - -static Reg* -findjump(BB *b) -{ - Reg *r, *l; - - r = b->first; - l = b->last; - - for(;;) { - if(r->prog->as == AJMP) - break; - if(r == l) { - diag(Z, "findjump botch"); - break; - } - r = r->link; - } - return r; -} - -static BB* -findset(int r) -{ - BB *s, **p; - int n, n2; - - if(r < ordered[0]->first->rpo) - return nil; - n = bcount; - p = ordered; - while(n > 0) { - n2 = n >> 1; - s = p[n2]; - if(r < s->first->rpo) { - n = n2; - continue; - } - if(r > s->last->rpo) { - n2++; - p += n2; - n -= n2; - continue; - } - return s; - } - diag(Z, "findset botch"); - return nil; -} - -static void -wound(Reg *r) -{ - BB *b, *p, **n; - BBset *s; - - b = findset(r->rpo); - if(b == nil) - return; - s = b->set; - if(s == nil) - return; - for(n = &s->ents; (p = *n) != nil; n = &(*n)->link) { - if(p == b) { - *n = b->link; - b->link = wounded; - wounded = b; - bbsrecalc(s); - return; - } - } -} - -static void -printbl(Reg *l) -{ - if(l == nil) { - print("Z"); - return; - } - - print("%ld", l->rpo); - while((l = l->p2link) != nil) - print(" %ld", l->rpo); -} - -static void -appset(Reg *e, Reg *s) -{ - for(;;) { - if(s->p2link == R) { - s->p2link = e; - return; - } - s = s->p2link; - } -} - -static Reg* -delset(Reg *e, Reg *s) -{ - Reg *c, *l; - - c = s; - l = nil; - for(;;) { - if(e == c) { - if(l == nil) - return s->p2link; - l->p2link = c->p2link; - return s; - } - l = c; - c = c->p2link; - if(c == nil) - return s; - } -} - -static void -redest(Reg *s, Reg *d) -{ - while(s != R) { - s->s2 = d; - s = s->p2link; - } -} - -static void -changedest(Reg *s, Reg *d, int x) -{ - Reg *l; - - if(bdebug) { - print("change %ld [", s->rpo); - printbl(s->p2); - print("] -> %ld [", d->rpo); - printbl(d->p2); - print("]\n"); - } - - if(s->p2 == nil) { -// print("deadjmp\n"); - return; - } - - l = s->p2; - for(;;) { - if(bdebug) - print("s2 %ld = %ld\n", l->rpo, d->rpo); - l->s2 = d; - wound(l); - if(l->p2link == nil) - break; - l = l->p2link; - } - - if(x) { - l->p2link = delset(s, d->p2); - d->p2 = s->p2; - } - else { - l->p2link = d->p2; - d->p2 = s->p2; - s->p2 = nil; - } - - if(bdebug) { - print("result ["); - printbl(d->p2); - print("]\n"); - } - - bchange = 1; -} - -static void -bexcise(BB *b) -{ - Reg *r, *l; - - l = b->last; - r = b->first; - if(bdebug) - print("excise %ld to %ld\n", r->rpo, l->rpo); - for(;;) { - r->prog->as = ANOP; - r->prog->to.type = D_NONE; - r->p2 = R; - if(r->s2 != R) { - r->s2->p2 = delset(r, r->s2->p2); - r->s2 = R; - } - if(r == l) - break; - r = r->link; - } -} - -static int -backtrack(Reg *s, Reg *d) -{ - int i; - char l[BINST], r[BINST]; - -//print("backtrack %ld %ld\n", Rn(s), Rn(d)); - i = 0; - while(s != nil && d != nil) { - if(snprint(l, BINST, "%P", s->prog) == BINST) - break; - if(snprint(r, BINST, "%P", d->prog) == BINST) - break; -//print("%s\t%s\n", l, r); - if(strcmp(l, r) != 0) - break; - i++; - s = s->p2link; - d = d->p2link; - } - return i; -} - -static void -checktails(void) -{ - int c; - Reg *r; - - c = 0; - for(r = firstr; r->link != R; r = r->link) { - if(r->prog->as == AJMP && r->s2 != nil) - c += backtrack(r->p1, r->s2->p1); - } - - if(c > 0) - print("tails %s %d\n", firstr->prog->from.sym->name, c); -} - -static void -process(BBset *s) -{ - Reg *h; - BB *f, *o, *p, *t; - - if(bdebug) - print("process %d %x %x\n", s->damage, s->hash[0], s->hash[1]); - f = s->ents; - if(f->flags & Bjo) { - s->ents = nil; - h = findjump(f)->s2; - o = nil; - while(f != nil) { - t = f->link; - if((f->flags & Bjo) != 0 && f->first->s2 != f->first) { - changedest(f->first, h, 1); - bexcise(f); - } - else { - f->link = o; - o = f; - } - f = t; - } - s->ents = o; - } - else { - o = nil; - p = nil; - while(f != nil) { - t = f->link; - if((f->flags & (Bpre|Bpin)) != 0 || (f->last->link == R)) { - f->link = p; - p = f; - } - else { - f->link = o; - o = f; - } - f = t; - } - if(o == nil) { - diag(Z, "all Bpre"); - return; - } - if(p == nil) { - p = o; - o = p->link; - p->link = nil; - s->ents = p; - } - else - s->ents = p; - - h = p->first; - // oblit o list repl with jmp to h - while(o != nil) { - changedest(o->first, h, 1); - bexcise(o); - o = o->link; - } - - bbsrecalc(s); - } -} - -static void -iterate(void) -{ - BBset *s; - BB *b, *t; - - heapn = 0; - - for(;;) { - for(b = wounded; b != nil; b = t) { - t = b->link; - enterbb(b); - } - wounded = nil; - - for(s = recalc; s != nil; s = s->link) - calcdamage(s); - recalc = nil; - - if(heapn == 0) - return; - - s = heap[1]; - heapremove(s); - process(s); - } -} - -static void -cleanup(void) -{ - int i; - BB *l, *n; - BBset *b, *t; - - for(i = 0; i < BBHASH; i++) { - b = bbhash[i]; - bbhash[i] = nil; - while(b != nil) { - t = b->next; - bsfree(b); - b = t; - } - } - for(i = 0; i < bcount; i++) - bfree(ordered[i]); - for(l = bbaux; l != nil; l = n) { - n = l->aux; - bfree(l); - } - bbaux = nil; -} - -static void -prreg(Reg *r) -{ - Prog *p; - - p = r->prog; - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->rpo; - print("%ld:%P\tr %lX ", r->rpo, r->prog, r->regu); - print("p1 %ld p2 %ld p2l %ld s1 %ld s2 %ld link %ld", - Rn(r->p1), Rn(r->p2), Rn(r->p2link), - Rn(r->s1), Rn(r->s2), Rn(r->link)); - if(!r->active) - print(" d"); -// print(" %p %p\n", r->prog, r->prog->link); - print("\n"); -} - -static void prfunc(char*); - -static void -checkr(int d) -{ - Prog *p; - Reg *r, *t; - - for(r = firstr; r->link != R; r = r->link) { - for(p = r->prog->link; p != P && p != r->link->prog; p = p->link) - ; - if(p == P) { - print("%ld: bad prog link\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - if(r->s1 != R && (r->s1 != r->link || r->link->p1 != r)) { - print("%ld: bad s1 p1\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - if(r->s2 != R && r->s2->p2 == nil) { - print("%ld: no p2 for s2\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - if(r->p2 != R) { - t = r->p2->s2; - while(t != r) { - t = t->p2link; - if(t == R) { - print("%ld: bad s2 for p2\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - } - } - } -} - -static void -prfunc(char *s) -{ - Reg *r; - - if(s != nil) - print("%s structure %s\n", s, firstr->prog->from.sym->name); - for(r = firstr; r != R; r = r->link) - prreg(r); - if(s != nil) { - print("end\n"); - checkr(0); - } -} - -/* find p in r's list and replace with l */ -static void -adjprog(Reg *r, Prog *p, Prog *l) -{ - Prog *t, **n; - - for(n = &r->prog->link; (t = *n) != nil; n = &t->link) { - if(t == p) { - *n = l; - return; - } - } - print("adjprog botch\n"); - abort(); -} - -static void -jumptojump(void) -{ - Reg *r; - - for(r = firstr; r != R; r = r->link) { - if(r->prog->as == AJMP && r->p2 != R && r->s2 != r) { - if(bdebug) - print("jump as dest %ld -> %ld\n", r->rpo, r->s2->rpo); - changedest(r, r->s2, 0); - bchange++; - } - } -} - -/* drag a tail to replace a jump. seems to be a bad idea. */ -static void -rearrange(void) -{ - int i; - Reg *j, *t; - BB *b, *p, *s; - - for(i = 0; i < bcount; i++) { - b = ordered[i]; - if(b->flags & Bdel) - continue; - j = b->last; - if(j->prog->as == AJMP && j->s2->p1 == R) { - t = j->s2; - if(t == b->first) - continue; - s = findset(t->rpo); - if(s == nil) { - diag(Z, "no self"); - continue; - } - if(s == ordered[0]) - continue; - if(s->flags & Bdel) - continue; - if(s->last->link == R) - continue; - if(bdebug) - print("drag %ld to %ld\n", t->rpo, j->rpo); - p = findset(t->rpo - 1); - if(p == nil) { - diag(Z, "no predec"); - continue; - } - if(p->last->link != t) { - diag(Z, "bad predec %ld %ld", p->last->rpo, t->rpo); - continue; - } - - /* poison everything in sight */ - b->flags |= Bdel; - s->flags |= Bdel; - findset(j->link->rpo)->flags |= Bdel; - findset(s->last->link->rpo)->flags |= Bdel; - - /* remove */ - adjprog(p->last, t->prog, s->last->link->prog); - p->last->link = s->last->link; - - /* fix tail */ - adjprog(s->last, s->last->link->prog, j->link->prog); - s->last->link = j->link; - - /* fix head */ - adjprog(j, j->link->prog, t->prog); - j->link = t; - - /* nop the jump */ - j->prog->as = ANOP; - j->prog->to.type = D_NONE; - j->s2 = nil; - j->link->p2 = delset(j, j->link->p2); - j->s1 = t; - t->p1 = j; - if(bcheck) - checkr(1); - bchange++; - } - } -} - -void -jumptodot(void) -{ - Reg *r; - - for(r = firstr; r != R; r = r->link) { - if(r->prog->as == AJMP && r->s2 == r->link) { - if(debug['v']) - print("jump to next %ld\n", r->rpo); - r->prog->as = ANOP; - r->prog->to.type = D_NONE; - r->s2 = nil; - r->link->p2 = delset(r, r->link->p2); - findset(r->rpo)->flags |= Bdel; - findset(r->link->rpo)->flags |= Bdel; - bchange++; - } - } -} - -void -comtarg(void) -{ - int n; - BB *b, *c; - Reg *r, *l, *p, *t; - -loop: - bchange = 0; - - /* excise NOPS because they just get in the way */ - /* some have p2 because they are excised labelled moves */ - - if(debug['v']) { - n = 0; - for(r = firstr; r != R; r = r->link) - r->rpo = n++; - prfunc("prenop"); - } - - r = firstr; - l = r->link; - while(l != R) { - if(l->prog->as == ANOP) { - t = l->p1; - p = l->p2; -if(dbg) print("nop %ld [", l->rpo); -if(dbg) printbl(p); - for(;;) { - adjprog(r, l->prog, l->prog->link); - r->link = l->link; - l->link = freer; - freer = l; - l = r->link; - if(l->prog->as != ANOP) - break; -if(dbg) print("] %ld [", l->rpo); -if(dbg) printbl(l->p2); - if(p == R) - p = l->p2; - else if(l->p2 != nil) - appset(l->p2, p); - } -if(dbg) print("] %ld [", l->rpo); -if(dbg) printbl(l->p2); - if(p != R) { - redest(p, l); - if(l->p2 != R) - appset(p, l->p2); - else - l->p2 = p; - } -if(dbg) print("] -> ["); -if(dbg) printbl(l->p2); -if(dbg) print("]\n"); - if(r->s1 != R) - r->s1 = l; - l->p1 = t; - } - r = l; - l = r->link; - } - - n = 0; - for(r = firstr; r != R; r = r->link) - r->rpo = n++; - - if(debug['v']) - prfunc("input"); - - firstbb = nil; - lastbb = nil; - - if(debug['v']) - print("bbstart\n"); - - n = 0; - r = firstr; - do { - b = bba(); - b->first = r; - for(;;) { - l = r; - r = r->link; - switch(l->prog->as) { - case ARET: - case AJMP: - case AIRETL: - goto out; - } - if(r->p2 != R) - break; - } - out: - b->last = l; - if(lastbb == nil) - firstbb = b; - else - lastbb->link = b; - lastbb = b; - if(bdebug) - print("BB %ld %ld\n", b->first->rpo, b->last->rpo); - n++; - } while(r != R); - - if(debug['v']) - print("end\n"); - - if(n > bsize) { - bsize = n * 3 / 2; - if(bsize < BBINIT) - bsize = BBINIT; - ordered = alloc(bsize * sizeof(*ordered)); - heap = alloc((bsize + 1) * sizeof(*ordered)); - } - - if(debug['v']) - print("preprocstart\n"); - - n = 0; - for(b = firstbb; b != nil; b = c) { - c = b->link; - preproc(b, n++); - } - - if(debug['v']) - print("end\n"); - - bcount = n; - - jumptojump(); - - if(debug['v']) - print("iteratestart\n"); - - iterate(); -//checktails(); - - if(debug['v']) - print("end\n"); - - if(debug['v']) - print("extrastart\n"); - - jumptodot(); -// rearrange(); - - if(debug['v']) - print("end\n"); - - cleanup(); - if(bballoc || bbsalloc) - diag(Z, "bballoc %d %d", bballoc, bbsalloc); - - if(debug['v']) - prfunc("output"); - - if(1 && bchange) - goto loop; -} diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/bound.h --- a/sys/src/cmd/8c/bound.h Fri Mar 02 10:40:01 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Bounding Box stuff (brucee 04/03/30). - */ - -#include -#include - -typedef struct BB BB; -typedef struct BBset BBset; -typedef uchar Hval[SHA1dlen]; - -#define BBEQ(a, b) (memcmp((a), (b), SHA1dlen) == 0) -#define BBMKHASH(b, n, h) sha1((uchar *)(b), (n), (h), nil) -#define BBCP(d, s) memmove(d, s, SHA1dlen) - -enum -{ - Bpre = 1 << 0, /* has a flow in */ - Bjo = 1 << 1, /* a jump only */ - Bbig = 1 << 2, /* too big */ - Bdel = 1 << 3, /* deleted or not of interest */ - Bpin = 1 << 4, /* pinned by embedded labels */ - - BBHASH = 64, /* power of 2 <= 256 */ - BBMASK = BBHASH - 1, - - BBINIT = 128, - BBBIG = 64, - BBBSIZE = 8192, - BINST = 128, - - COSTHI = 0x7F, - COSTJO = 0xFF, -}; - -struct BB -{ - Reg* first; - Reg* last; - BBset* set; - BB* link; - BB* aux; - short flags; - short len; -}; - -struct BBset -{ - Hval hash; - BB* ents; - BBset* next; - BBset* link; - short index; - uchar damage; - uchar recalc; -}; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/cgen.c --- a/sys/src/cmd/8c/cgen.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/cgen.c Tue Mar 06 14:42:52 2012 +0100 @@ -25,6 +25,12 @@ l = n->left; r = n->right; o = n->op; +// Go's version does the following, but it's the wrong place: doesn't allow assignment +// if(o == OEXREG || nn != Z && nn->op == OEXREG) { +// gmove(n, nn); +// return; +// } + if(n->addable >= INDEXED) { if(nn == Z) { switch(o) { @@ -244,7 +250,7 @@ if(n->op == OADD && l->op == OASHL && l->right->op == OCONST && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) { c = l->right->vconst; - if(c > 0 && c <= 3) { + if(c > 0 && c <= 3 && nareg(1) >= 4) { if(l->left->complex >= r->complex) { regalloc(&nod, l->left, nn); cgen(l->left, &nod); @@ -887,6 +893,7 @@ break; case OFUNC: + l = uncomma(l); if(l->complex >= FNX) { if(l->op != OIND) diag(n, "bad function call"); @@ -1824,6 +1831,12 @@ gins(ACLD, Z, Z); gins(AREP, Z, Z); gins(AMOVSL, Z, Z); + if(w & (SZ_LONG-1)) { + /* odd length of packed structure */ + gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3); + gins(AREP, Z, Z); + gins(AMOVSB, Z, Z); + } if(c & 4) { gins(APOPL, Z, &nod3); reg[D_CX]--; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/cgen64.c --- a/sys/src/cmd/8c/cgen64.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/cgen64.c Tue Mar 06 14:42:52 2012 +0100 @@ -188,70 +188,6 @@ freepair(n); } -/* generate a cast t from n to tt */ -static void -cast(Node *n, Type *t, Node *nn) -{ - Node *r; - - r = new(OCAST, n, Z); - r->type = t; - sugen(r, nn, 8); -} - -static void -swapregs(Node *a, Node *b) -{ - int t; - - t = a->reg; - a->reg = b->reg; - b->reg = t; -} - -static void -swappairs(Node *a, Node *b) -{ - swapregs(a->left, b->left); - swapregs(a->right, b->right); -} - -static int -saveme(Node *n) -{ - int r; - - r = n->reg; - return r >= D_AX && r <= D_DI; -} - -static void -saveit(Node *n, Node *t, Node *r) -{ - Node nod; - - if(saveme(n)) { - t->reg = n->reg; - gins(AMOVL, t, r); - r->xoffset += SZ_LONG; - if(n->reg == D_AX) { - regalloc(&nod, n, Z); - regfree(n); - n->reg = nod.reg; - } - } -} - -static void -restoreit(Node *n, Node *t, Node *r) -{ - if(saveme(n)) { - t->reg = n->reg; - gins(AMOVL, r, t); - r->xoffset += SZ_LONG; - } -} - enum { /* 4 only, see WW */ @@ -319,26 +255,6 @@ return t; } -static int -forcereg(Node *d, int r, int o, Node *t) -{ - int a; - - if(d->reg != D_NONE) - diag(Z, "force alloc"); - d->reg = r; - a = 0; - if(reg[r]) { - reg[o]++; - regalloc(t, d, Z); - a = 1; - gins(AMOVL, d, t); - reg[o]--; - } - reg[r]++; - return a; -} - /* try to steal a reg */ static int getreg(Node **np, Node *t, int r) diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/div.c --- a/sys/src/cmd/8c/div.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/div.c Tue Mar 06 14:42:52 2012 +0100 @@ -6,7 +6,7 @@ * SIGPLAN Notices, Vol. 29, June 1994, page 61. */ -#define TN(n) (1ULL << (n)) +#define TN(n) ((uvlong)1 << (n)) #define T31 TN(31) #define T32 TN(32) diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/enam.c --- a/sys/src/cmd/8c/enam.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/enam.c Tue Mar 06 14:42:52 2012 +0100 @@ -333,5 +333,52 @@ "DYNT", "INIT", "SIGNAME", + "FCOMI", + "FCOMIP", + "FUCOMI", + "FUCOMIP", + "CMPXCHGB", + "CMPXCHGL", + "CMPXCHGW", + "CMOVLCC", + "CMOVLCS", + "CMOVLEQ", + "CMOVLGE", + "CMOVLGT", + "CMOVLHI", + "CMOVLLE", + "CMOVLLS", + "CMOVLLT", + "CMOVLMI", + "CMOVLNE", + "CMOVLOC", + "CMOVLOS", + "CMOVLPC", + "CMOVLPL", + "CMOVLPS", + "CMOVWCC", + "CMOVWCS", + "CMOVWEQ", + "CMOVWGE", + "CMOVWGT", + "CMOVWHI", + "CMOVWLE", + "CMOVWLS", + "CMOVWLT", + "CMOVWMI", + "CMOVWNE", + "CMOVWOC", + "CMOVWOS", + "CMOVWPC", + "CMOVWPL", + "CMOVWPS", + "FCMOVCC", + "FCMOVCS", + "FCMOVEQ", + "FCMOVHI", + "FCMOVLS", + "FCMOVNE", + "FCMOVNU", + "FCMOVUN", "LAST", }; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/gc.h --- a/sys/src/cmd/8c/gc.h Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/gc.h Tue Mar 06 14:42:52 2012 +0100 @@ -240,6 +240,7 @@ void gargs(Node*, Node*, Node*); void garg1(Node*, Node*, Node*, int, Node**); Node* nodconst(long); +int nareg(int); Node* nodfconst(double); int nodreg(Node*, Node*, int); int isreg(Node*, int); @@ -298,7 +299,7 @@ int rcmp(const void*, const void*); void regopt(Prog*); void addmove(Reg*, int, int, int); -Bits mkvar(Reg*, Adr*); +Bits mkvar(Reg*, Adr*, int); void prop(Reg*, Bits, Bits); void loopit(Reg*, long); void synch(Reg*, Bits); @@ -336,11 +337,6 @@ #define D_LO D_NONE /* - * bound - */ -void comtarg(void); - -/* * com64 */ int cond(int); diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/machcap.c --- a/sys/src/cmd/8c/machcap.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/machcap.c Tue Mar 06 14:42:52 2012 +0100 @@ -53,6 +53,7 @@ case OANDAND: case OOROR: case ONOT: + case ODOT: return 1; case OASADD: diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/mkfile --- a/sys/src/cmd/8c/mkfile Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/mkfile Tue Mar 06 14:42:52 2012 +0100 @@ -2,7 +2,6 @@ TARG=8c OFILES=\ - bound.$O\ cgen.$O\ cgen64.$O\ div.$O\ @@ -33,7 +32,6 @@ mk install mk clean -bound.$O: bound.h %.$O: ../cc/%.c $CC $CFLAGS ../cc/$stem.c diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/peep.c --- a/sys/src/cmd/8c/peep.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/peep.c Tue Mar 06 14:42:52 2012 +0100 @@ -67,8 +67,6 @@ pc = 0; /* speculating it won't kill */ loop1: - if(debug['b']) - comtarg(); t = 0; for(r=firstr; r!=R; r=r->link) { @@ -277,6 +275,9 @@ case ACWD: case ACDQ: + case ASTOSB: + case ASTOSL: + case AMOVSB: case AMOVSL: case AFSTSW: return 0; @@ -641,10 +642,21 @@ return 2; goto caseread; - case AMOVSL: case AREP: case AREPN: - if(v->type == D_CX || v->type == D_DI || v->type == D_SI) + if(v->type == D_CX) + return 2; + goto caseread; + + case AMOVSB: + case AMOVSL: + if(v->type == D_DI || v->type == D_SI) + return 2; + goto caseread; + + case ASTOSB: + case ASTOSL: + if(v->type == D_AX || v->type == D_DI) return 2; goto caseread; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/reg.c --- a/sys/src/cmd/8c/reg.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/reg.c Tue Mar 06 14:42:52 2012 +0100 @@ -119,7 +119,7 @@ r1->s1 = R; } - bit = mkvar(r, &p->from); + bit = mkvar(r, &p->from, p->as==AMOVL); if(bany(&bit)) switch(p->as) { /* @@ -139,7 +139,7 @@ break; } - bit = mkvar(r, &p->to); + bit = mkvar(r, &p->to, 0); if(bany(&bit)) switch(p->as) { default: @@ -224,7 +224,9 @@ */ case AFMOVDP: case AFMOVFP: + case AFMOVLP: case AFMOVVP: + case AFMOVWP: case ACALL: for(z=0; ztype; r->regu |= doregbits(t); r->regu |= doregbits(a->index); + et = a->etype; switch(t) { default: goto none; + case D_INDIR+D_GS: + if(!isro || 1) + goto none; + n = t; + {static Sym er; a->sym = &er;} + a->sym->name = "$extreg"; + break; case D_ADDR: a->type = a->index; - bit = mkvar(r, a); + bit = mkvar(r, a, 0); for(z=0; ztype = t; @@ -674,7 +684,6 @@ goto none; if(s->name[0] == '.') goto none; - et = a->etype; o = a->offset; v = var; for(i=0; iuse1.b[z] & bb) { change += CREF * r->loop; - if(p->as == AFMOVL) + if(p->as == AFMOVL || p->as == AFMOVW) if(BtoR(bb) != D_F0) change = -CINF; if(debug['R'] && debug['v']) @@ -1018,7 +1027,7 @@ if((r->use2.b[z]|r->set.b[z]) & bb) { change += CREF * r->loop; - if(p->as == AFMOVL) + if(p->as == AFMOVL || p->as == AFMOVW) if(BtoR(bb) != D_F0) change = -CINF; if(debug['R'] && debug['v']) @@ -1028,7 +1037,7 @@ if(STORE(r) & r->regdiff.b[z] & bb) { change -= CLOAD * r->loop; - if(p->as == AFMOVL) + if(p->as == AFMOVL || p->as == AFMOVW) if(BtoR(bb) != D_F0) change = -CINF; if(debug['R'] && debug['v']) diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/sgen.c --- a/sys/src/cmd/8c/sgen.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/sgen.c Tue Mar 06 14:42:52 2012 +0100 @@ -88,6 +88,10 @@ n->addable = 11; break; + case OEXREG: + n->addable = 12; + break; + case OREGISTER: n->addable = 12; break; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8c/txt.c --- a/sys/src/cmd/8c/txt.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8c/txt.c Tue Mar 06 14:42:52 2012 +0100 @@ -158,7 +158,8 @@ cursafe = regs; } -int nareg(void) +int +nareg(int notbp) { int i, n; @@ -166,6 +167,8 @@ for(i=D_AX; i<=D_DI; i++) if(reg[i] == 0) n++; + if(notbp && reg[D_BP] == 0) + n--; return n; } @@ -306,6 +309,7 @@ if(reg[i] == 0) goto out; diag(tn, "out of fixed registers"); +abort(); goto err; case TFLOAT: @@ -430,6 +434,11 @@ a->sym = S; break; + case OEXREG: + a->type = D_INDIR + D_GS; + a->offset = n->reg - 1; + a->etype = n->etype; + break; case OIND: naddr(n->left, a); @@ -1355,7 +1364,15 @@ exreg(Type *t) { - USED(t); + int o; + + if(typechlp[t->etype]){ + if(exregoffset >= 32) + return 0; + o = exregoffset; + exregoffset += 4; + return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */ + } return 0; } diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8l/l.h --- a/sys/src/cmd/8l/l.h Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8l/l.h Tue Mar 06 14:42:52 2012 +0100 @@ -37,7 +37,7 @@ Sym* u1sym; } u1; short type; - char index; + uchar index; char scale; }; @@ -58,11 +58,12 @@ Prog* pcond; /* work on this */ long pc; long line; + short as; + char width; /* fake for DATA */ + char ft; /* oclass cache */ + char tt; uchar mark; /* work on these */ uchar back; - - short as; - char width; /* fake for DATA */ }; struct Auto { @@ -203,6 +204,7 @@ #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int +#pragma varargck type "R" uint #pragma varargck type "S" char* #pragma varargck argpos diag 1 @@ -270,7 +272,7 @@ 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; @@ -345,3 +347,8 @@ void xfol(Prog*); int zaddr(uchar*, Adr*, Sym*[]); void zerosig(char*); + +#pragma varargck type "D" Adr* +#pragma varargck type "P" Prog* +#pragma varargck type "R" int +#pragma varargck type "A" int diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8l/list.c --- a/sys/src/cmd/8l/list.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8l/list.c Tue Mar 06 14:42:52 2012 +0100 @@ -24,18 +24,18 @@ switch(p->as) { case ATEXT: if(p->from.scale) { - sprint(str, "(%ld) %A %D,%d,%D", + snprint(str, sizeof(str), "(%ld) %A %D,%d,%D", p->line, p->as, &p->from, p->from.scale, &p->to); break; } default: - sprint(str, "(%ld) %A %D,%D", + snprint(str, sizeof(str), "(%ld) %A %D,%D", p->line, p->as, &p->from, &p->to); break; case ADATA: case AINIT: case ADYNT: - sprint(str, "(%ld) %A %D/%d,%D", + snprint(str, sizeof(str), "(%ld) %A %D/%d,%D", p->line, p->as, &p->from, p->from.scale, &p->to); break; } @@ -55,7 +55,7 @@ int Dconv(Fmt *fp) { - char str[40], s[20]; + char str[STRINGSZ+40], s[20]; Adr *a; int i; @@ -63,15 +63,15 @@ i = a->type; if(i >= D_INDIR) { if(a->offset) - sprint(str, "%ld(%R)", a->offset, i-D_INDIR); + snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR); else - sprint(str, "(%R)", i-D_INDIR); + snprint(str, sizeof(str), "(%R)", i-D_INDIR); goto brk; } switch(i) { default: - sprint(str, "%R", i); + snprint(str, sizeof(str), "%R", i); break; case D_NONE: @@ -81,57 +81,57 @@ case D_BRANCH: if(bigP != P && bigP->pcond != P) if(a->sym != S) - sprint(str, "%lux+%s", bigP->pcond->pc, + snprint(str, sizeof(str), "%lux+%s", bigP->pcond->pc, a->sym->name); else - sprint(str, "%lux", bigP->pcond->pc); + snprint(str, sizeof(str), "%lux", bigP->pcond->pc); else - sprint(str, "%ld(PC)", a->offset); + snprint(str, sizeof(str), "%ld(PC)", a->offset); break; case D_EXTERN: - sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset); break; case D_STATIC: - sprint(str, "%s<%d>+%ld(SB)", a->sym->name, + snprint(str, sizeof(str), "%s<%d>+%ld(SB)", a->sym->name, a->sym->version, a->offset); break; case D_AUTO: - sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset); break; case D_PARAM: if(a->sym) - sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); + snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset); else - sprint(str, "%ld(FP)", a->offset); + snprint(str, sizeof(str), "%ld(FP)", a->offset); break; case D_CONST: - sprint(str, "$%ld", a->offset); + snprint(str, sizeof(str), "$%ld", a->offset); break; case D_FCONST: - sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); + snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); break; case D_SCONST: - sprint(str, "$\"%S\"", a->scon); + snprint(str, sizeof(str), "$\"%S\"", a->scon); break; case D_ADDR: a->type = a->index; a->index = D_NONE; - sprint(str, "$%D", a); + snprint(str, sizeof(str), "$%D", a); a->index = a->type; a->type = D_ADDR; goto conv; } brk: if(a->index != D_NONE) { - sprint(s, "(%R*%d)", a->index, a->scale); + snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale); strcat(str, s); } conv: @@ -218,9 +218,9 @@ r = va_arg(fp->args, int); if(r >= D_AL && r <= D_NONE) - sprint(str, "%s", regstr[r-D_AL]); + snprint(str, sizeof(str), "%s", regstr[r-D_AL]); else - sprint(str, "gok(%d)", r); + snprint(str, sizeof(str), "gok(%d)", r); return fmtstrcpy(fp, str); } diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8l/obj.c --- a/sys/src/cmd/8l/obj.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8l/obj.c Tue Mar 06 14:42:52 2012 +0100 @@ -95,8 +95,13 @@ 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; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8l/pass.c --- a/sys/src/cmd/8l/pass.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8l/pass.c Tue Mar 06 14:42:52 2012 +0100 @@ -311,7 +311,7 @@ switch(s->type) { default: /* diag prints TNAME first */ - diag("%s is undefined", s->name); + diag("undefined: %s", s->name); s->type = STEXT; s->value = vexit; break; /* or fall through to set offset? */ @@ -678,14 +678,14 @@ 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 -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/8l/span.c --- a/sys/src/cmd/8l/span.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/8l/span.c Tue Mar 06 14:42:52 2012 +0100 @@ -304,6 +304,24 @@ } int +prefixof(Adr *a) +{ + switch(a->type) { + case D_INDIR+D_CS: + return 0x2e; + case D_INDIR+D_DS: + return 0x3e; + case D_INDIR+D_ES: + return 0x26; + case D_INDIR+D_FS: + return 0x64; + case D_INDIR+D_GS: + return 0x65; + } + return 0; +} + +int oclass(Adr *a) { long v; @@ -334,6 +352,8 @@ return Yax; case D_CL: + return Ycl; + case D_DL: case D_BL: case D_AH: @@ -606,7 +626,7 @@ } if(t >= D_INDIR) { t -= D_INDIR; - if(t == D_NONE) { + if(t == D_NONE || D_CS <= t && t <= D_GS) { *andptr++ = (0 << 6) | (5 << 0) | (r << 3); put4(v); return; @@ -767,6 +787,7 @@ ASHRL, Ycol, Yml, 6, 0xac,0xad,0,0, /* extra imul */ + AIMULW, Yml, Yrl, 7, Pq,0xaf,0,0, AIMULL, Yml, Yrl, 7, Pm,0xaf,0,0, 0 }; @@ -821,7 +842,14 @@ Prog *q, pp; uchar *t; int z, op, ft, tt; - long v; + long v, pre; + + pre = prefixof(&p->from); + if(pre) + *andptr++ = pre; + pre = prefixof(&p->to); + if(pre) + *andptr++ = pre; o = &optab[p->as]; ft = oclass(&p->from) * Ymax; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/acid.c --- a/sys/src/cmd/cc/acid.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/acid.c Tue Mar 06 14:42:52 2012 +0100 @@ -90,6 +90,8 @@ if(types[TINT]->width != types[TSHORT]->width) warn(Z, "acidmember int not long or short"); } + if(types[TIND]->width == types[TUVLONG]->width) + acidchar[TIND] = 'Y'; } diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/cc.h --- a/sys/src/cmd/cc/cc.h Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/cc.h Tue Mar 06 14:42:52 2012 +0100 @@ -22,11 +22,11 @@ #define NHUNK 50000L #define BUFSIZ 8192 -#define NSYMB 500 +#define NSYMB 1500 #define NHASH 1024 #define STRINGSZ 200 #define HISTSZ 20 -#define YYMAXDEPTH 500 +#define YYMAXDEPTH 1500 #define NTERM 10 #define MAXALIGN 7 @@ -294,6 +294,7 @@ OINDEX, OFAS, OREGPAIR, + OEXREG, OEND }; @@ -477,6 +478,7 @@ EXTERN int fproundflg; EXTERN int profileflg; EXTERN int ncontin; +EXTERN int newvlongcode; EXTERN int canreach; EXTERN int warnreach; EXTERN Bits zbits; @@ -614,7 +616,7 @@ int sametype(Type*, Type*); ulong sign(Sym*); ulong signature(Type*); -void suallign(Type*); +void sualign(Type*); void tmerge(Type*, Sym*); void walkparam(Node*, int); void xdecl(int, Type*, Sym*); @@ -632,6 +634,8 @@ int tcomx(Node*); int tlvalue(Node*); void constas(Node*, Type*, Type*); +Node* uncomma(Node*); +Node* uncomargs(Node*); /* * con.c diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/cc.y --- a/sys/src/cmd/cc/cc.y Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/cc.y Tue Mar 06 14:42:52 2012 +0100 @@ -8,12 +8,14 @@ struct { Type* t; - char c; + uchar c; } tycl; struct { Type* t1; Type* t2; + Type* t3; + uchar c; } tyty; struct { @@ -895,16 +897,22 @@ { $$.t1 = strf; $$.t2 = strl; + $$.t3 = lasttype; + $$.c = lastclass; strf = T; strl = T; lastbit = 0; firstbit = 1; + lastclass = CXXX; + lasttype = T; } edecl '}' { $$ = strf; strf = $2.t1; strl = $2.t2; + lasttype = $2.t3; + lastclass = $2.c; } zctlist: @@ -995,7 +1003,7 @@ if($$->link != T) diag(Z, "redeclare tag: %s", $2->name); $$->link = $4; - suallign($$); + sualign($$); } | LSTRUCT sbody { @@ -1003,7 +1011,7 @@ sprint(symb, "_%d_", taggen); $$ = dotag(lookup(), TSTRUCT, autobn); $$->link = $2; - suallign($$); + sualign($$); } | LUNION ltag { @@ -1020,7 +1028,7 @@ if($$->link != T) diag(Z, "redeclare tag: %s", $2->name); $$->link = $4; - suallign($$); + sualign($$); } | LUNION sbody { @@ -1028,7 +1036,7 @@ sprint(symb, "_%d_", taggen); $$ = dotag(lookup(), TUNION, autobn); $$->link = $2; - suallign($$); + sualign($$); } | LENUM ltag { diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/com.c --- a/sys/src/cmd/cc/com.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/com.c Tue Mar 06 14:42:52 2012 +0100 @@ -1,6 +1,15 @@ #include "cc.h" +typedef struct Com Com; +struct Com +{ + int n; + Node *t[500]; +}; + int compar(Node*, int); +static void comma(Node*); +static Node* commas(Com*, Node*); void complex(Node *n) @@ -15,6 +24,8 @@ prtree(n, "pre complex"); if(tcom(n)) return; + if(debug['y'] || 1) + comma(n); if(debug['t']) if(n->op != OCONST) prtree(n, "t complex"); @@ -273,8 +284,11 @@ goto bad; n->type = l->type; if(n->type->etype == TIND) - if(n->type->link->width < 1) - diag(n, "inc/dec of a void pointer"); + if(n->type->link->width < 1) { + snap(n->type->link); + if(n->type->link->width < 1) + diag(n, "inc/dec of a void pointer"); + } break; case OEQ: @@ -610,6 +624,8 @@ n->addable = 1; if(n->class == CEXREG) { n->op = OREGISTER; + if(thechar == '8') + n->op = OEXREG; n->reg = n->sym->offset; n->xoffset = 0; break; @@ -882,6 +898,101 @@ } /* + * hoist comma operators out of expressions + * (a,b) OP c => (a, b OP c) + * OP(a,b) => (a, OP b) + * a OP (b,c) => (b, a OP c) + */ + +static Node* +comargs(Com *com, Node *n) +{ + if(n != Z && n->op == OLIST){ + n->left = comargs(com, n->left); + n->right = comargs(com, n->right); + } + return commas(com, n); +} + +static Node* +commas(Com *com, Node *n) +{ + Node *t; + + if(n == Z) + return n; + switch(n->op){ + case OREGISTER: + case OINDREG: + case OCONST: + case ONAME: + case OSTRING: + /* leaf */ + return n; + + case OCOMMA: + t = commas(com, n->left); + if(com->n >= nelem(com->t)) + fatal(n, "comma list overflow"); + com->t[com->n++] = t; + return commas(com, n->right); + + case OFUNC: + n->left = commas(com, n->left); + n->right = comargs(com, n->right); + return n; + + case OCOND: + n->left = commas(com, n->left); + comma(n->right->left); + comma(n->right->right); + return n; + + case OANDAND: + case OOROR: + n->left = commas(com, n->left); + comma(n->right); + return n; + + case ORETURN: + comma(n->left); + return n; + } + n->left = commas(com, n->left); + if(n->right != Z) + n->right = commas(com, n->right); + return n; +} + +static void +comma(Node *n) +{ + Com com; + Node *nn; + + com.n = 0; + nn = commas(&com, n); + if(com.n > 0){ +if(debug['y'])print("n=%d\n", com.n); +if(debug['y']) prtree(nn, "res"); + if(nn != n) + *n = *nn; + while(com.n > 0){ +if(debug['y']) prtree(com.t[com.n-1], "tree"); + nn = new1(OXXX, Z, Z); + *nn = *n; + n->op = OCOMMA; + n->type = nn->type; + n->left = com.t[--com.n]; + n->right = nn; + n->lineno = n->left->lineno; + } +if(debug['y']) prtree(n, "final"); + }else if(n != nn) + fatal(n, "odd tree"); +} + +/* * general rewrite * (IND(ADDR x)) ==> x * (ADDR(IND x)) ==> x @@ -934,7 +1045,8 @@ if(n->op == OCONST) break; } - if(nocast(l->type, n->type)) { + if(nocast(l->type, n->type) && + (!typefd[l->type->etype] || typeu[l->type->etype] && typeu[n->type->etype])) { l->type = n->type; *n = *l; } @@ -1342,6 +1454,7 @@ else snprint(cmpbuf, sizeof cmpbuf, "%T %s %s", lt, cmps[relindex(n->op)], xbuf); +if(debug['y']) prtree(n, "strange"); warn(n, "useless or misleading comparison: %s", cmpbuf); return 0; } diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/com64.c --- a/sys/src/cmd/cc/com64.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/com64.c Tue Mar 06 14:42:52 2012 +0100 @@ -274,6 +274,8 @@ case ORETURN: case OAS: case OIND: + case OLIST: + case OCOMMA: return 1; case OADD: a = nodaddv; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/dcl.c --- a/sys/src/cmd/cc/dcl.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/dcl.c Tue Mar 06 14:42:52 2012 +0100 @@ -519,7 +519,7 @@ } void -suallign(Type *t) +sualign(Type *t) { Type *l; long o, w; @@ -581,7 +581,7 @@ return; default: - diag(Z, "unknown type in suallign: %T", t); + diag(Z, "unknown type in sualign: %T", t); break; } } @@ -1180,12 +1180,6 @@ { switch(t->etype) { - case TUNION: - case TSTRUCT: - if(t->width <= 0) - diag(Z, "incomplete structure: %s", t->tag->name); - break; - case TARRAY: t = typ(TIND, t->link); t->width = types[TIND]->width; @@ -1283,6 +1277,8 @@ diag(Z, "parameter cannot have class: %s", s->name); c = CPARAM; } + if(typesu[t->etype] && t->width <= 0) + diag(Z, "incomplete structure: %s", t->tag->name); adecl(c, t, s); } diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/macbody --- a/sys/src/cmd/cc/macbody Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/macbody Tue Mar 06 14:42:52 2012 +0100 @@ -25,7 +25,7 @@ char *cp; c = getnsc(); - if(!isalpha(c) && c != '_') { + if(!isalpha(c) && c != '_' && c < Runeself) { unget(c); return S; } @@ -33,7 +33,7 @@ if(cp <= symb+NSYMB-4) *cp++ = c; c = getc(); - if(isalnum(c) || c == '_') + if(isalnum(c) || c == '_' || c >= Runeself) continue; unget(c); break; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/pgen.c --- a/sys/src/cmd/cc/pgen.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/pgen.c Tue Mar 06 14:42:52 2012 +0100 @@ -105,10 +105,20 @@ warnreach = owarn; } +Node* +uncomma(Node *n) +{ + while(n != Z && n->op == OCOMMA) { + cgen(n->left, Z); + n = n->right; + } + return n; +} + void gen(Node *n) { - Node *l, nod; + Node *l, nod, rn; Prog *sp, *spc, *spb; Case *cn; long sbc, scc; @@ -129,6 +139,7 @@ case OLABEL: case OCASE: case OLIST: + case OCOMMA: case OBREAK: case OFOR: case OWHILE: @@ -151,6 +162,7 @@ break; case OLIST: + case OCOMMA: gen(n->left); rloop: @@ -163,7 +175,7 @@ complex(n); if(n->type == T) break; - l = n->left; + l = uncomma(n->left); if(l == Z) { noretval(3); gbranch(ORETURN); @@ -181,6 +193,20 @@ gbranch(ORETURN); break; } + if(newvlongcode && !typefd[n->type->etype]){ + regret(&rn, n); + regfree(&rn); + nod = znode; + nod.op = OAS; + nod.left = &rn; + nod.right = l; + nod.type = n->type; + nod.complex = l->complex; + cgen(&nod, Z); + noretval(2); + gbranch(ORETURN); + break; + } regret(&nod, n); cgen(l, &nod); regfree(&nod); @@ -531,6 +557,8 @@ int bcomplex(Node *n, Node *c) { + Node *b, nod; + complex(n); if(n->type != T) @@ -542,6 +570,17 @@ } if(c != Z && n->op == OCONST && deadheads(c)) return 1; + if(newvlongcode && 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]; + cgen(b, Z); + return 0; + } bool64(n); boolgen(n, 1, Z); return 0; diff -r e88fc68069f4 -r 4c0cd44c79c3 sys/src/cmd/cc/sub.c --- a/sys/src/cmd/cc/sub.c Fri Mar 02 10:40:01 2012 +0100 +++ b/sys/src/cmd/cc/sub.c Tue Mar 06 14:42:52 2012 +0100 @@ -1485,6 +1485,7 @@ OINDEX, 0, "INDEX", OFAS, 0, "FAS", OREGPAIR, 0, "REGPAIR", + OEXREG, 0, "EXREG", OEND, 0, "END", -1, 0, 0, };