diff options
Diffstat (limited to 'utils/vc')
| -rw-r--r-- | utils/vc/cgen.c | 2 | ||||
| -rw-r--r-- | utils/vc/gc.h | 9 | ||||
| -rw-r--r-- | utils/vc/mkfile | 8 | ||||
| -rw-r--r-- | utils/vc/peep.c | 2 | ||||
| -rw-r--r-- | utils/vc/sgen.c | 353 | ||||
| -rw-r--r-- | utils/vc/swt.c | 138 |
6 files changed, 29 insertions, 483 deletions
diff --git a/utils/vc/cgen.c b/utils/vc/cgen.c index 5d5262db..faaa0ade 100644 --- a/utils/vc/cgen.c +++ b/utils/vc/cgen.c @@ -497,6 +497,8 @@ cgen(Node *n, Node *nn) } else gopcode(OADD, nodconst(v), Z, &nod); gopcode(OAS, &nod, Z, &nod2); + if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */ + gins(ANOP, l, Z); regfree(&nod); if(l->addable < INDEXED) diff --git a/utils/vc/gc.h b/utils/vc/gc.h index 71aec5c1..29fc0bc5 100644 --- a/utils/vc/gc.h +++ b/utils/vc/gc.h @@ -58,6 +58,7 @@ struct Case long val; long label; char def; + char isv; }; #define C ((Case*)0) @@ -129,6 +130,7 @@ struct Rgn }; EXTERN long breakpc; +EXTERN long nbreak; EXTERN Case* cases; EXTERN Node constnode; EXTERN Node fconstnode; @@ -140,7 +142,6 @@ EXTERN Prog* lastp; EXTERN long maxargsafe; EXTERN int mnstring; EXTERN Multab multab[20]; -EXTERN int retok; EXTERN int hintabsize; EXTERN Node* nodrat; EXTERN Node* nodret; @@ -184,6 +185,7 @@ EXTERN long regbits; EXTERN long exregbits; EXTERN int change; +EXTERN int suppress; EXTERN Reg* firstr; EXTERN Reg* lastr; @@ -204,7 +206,7 @@ void codgen(Node*, Node*); void gen(Node*); void noretval(int); void xcom(Node*); -void bcomplex(Node*); +int bcomplex(Node*, Node*); void usedset(Node*, int); /* @@ -256,7 +258,8 @@ void gpseudo(int, Sym*, Node*); */ int swcmp(const void*, const void*); void doswit(Node*); -void swit1(C1*, int, long, Node*, Node*); +void swit1(C1*, int, long, Node*); +void swit2(C1*, int, long, Node*, Node*); void casf(void); void bitload(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*); diff --git a/utils/vc/mkfile b/utils/vc/mkfile index f17af88d..71adf1f4 100644 --- a/utils/vc/mkfile +++ b/utils/vc/mkfile @@ -7,6 +7,8 @@ OFILES=\ enam.$O\ list.$O\ peep.$O\ + pgen.$O\ + pswt.$O\ reg.$O\ sgen.$O\ swt.$O\ @@ -30,3 +32,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: v.out.h +# rc mkenam diff --git a/utils/vc/peep.c b/utils/vc/peep.c index 1feff699..5f635571 100644 --- a/utils/vc/peep.c +++ b/utils/vc/peep.c @@ -569,7 +569,7 @@ copyu(Prog *p, Adr *v, Adr *s) return 3; return 0; } - return 0; + /* not reached */ } int diff --git a/utils/vc/sgen.c b/utils/vc/sgen.c index c0fec8a3..6e70748b 100644 --- a/utils/vc/sgen.c +++ b/utils/vc/sgen.c @@ -1,345 +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)); - sp = p; - - /* - * isolate first argument - */ - if(REGARG) { - if(typesuv[thisfn->link->etype]) { - nod1 = *nodret->left; - nodreg(&nod, &nod1, REGARG); - gopcode(OAS, &nod, Z, &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); - gopcode(OAS, &nod, Z, &nod1); - } - } - - 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); - gbranch(ORETURN); - - if(!debug['N'] || debug['R'] || debug['P']) - regopt(sp); - - sp->to.offset += maxargsafe; -} - -void -gen(Node *n) -{ - Node *l, nod; - Prog *sp, *spc, *spb; - Case *cn; - long sbc, scc; - int 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); - 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->pc = 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; - } - gbranch(OGOTO); - if(n->pc) { - patch(p, n->pc); - 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); /* 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); - 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; - bcomplex(l); - 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) { @@ -564,17 +225,3 @@ xcom(Node *n) } } -void -bcomplex(Node *n) -{ - - complex(n); - if(n->type != T) - if(tcompat(n, T, n->type, tnot)) - n->type = T; - if(n->type != T) { - bool64(n); - boolgen(n, 1, Z); - } else - gbranch(OGOTO); -} diff --git a/utils/vc/swt.c b/utils/vc/swt.c index d5c72dc1..cdc58e1b 100644 --- a/utils/vc/swt.c +++ b/utils/vc/swt.c @@ -1,62 +1,17 @@ #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) +swit1(C1 *q, int nc, long def, Node *n) { - Case *c; - C1 *q, *iq; - long def, nc, i; Node tn; - - 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); + regalloc(&tn, ®node, Z); - swit1(iq, nc, def, n, &tn); + swit2(q, nc, def, n, &tn); regfree(&tn); } void -swit1(C1 *q, int nc, long def, Node *n, Node *tn) +swit2(C1 *q, int nc, long def, Node *n, Node *tn) { C1 *r; int i; @@ -84,22 +39,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) sp = p; gopcode(OEQ, n, tn, Z); patch(p, r->label); - swit1(q, i, def, n, tn); + swit2(q, i, def, n, tn); if(debug['W']) print("case < %.8lux\n", r->val); patch(sp, pc); - swit1(r+1, nc-i-1, def, n, tn); -} - -void -casf(void) -{ - Case *c; - - c = alloc(sizeof(*c)); - c->link = cases; - cases = c; + swit2(r+1, nc-i-1, def, n, tn); } void @@ -197,31 +142,6 @@ outstring(char *s, long n) return r; } -long -outlstring(ushort *s, long n) -{ - char buf[2]; - int c; - long r; - - 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; -} - int mulcon(Node *n, Node *nn) { @@ -314,16 +234,6 @@ loop: } 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) { long e, lw; @@ -615,35 +525,6 @@ zaddr(char *bp, Adr *a, int s) return bp; } -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) { @@ -660,6 +541,8 @@ align(long i, Type *t, int op) case Asu2: /* padding at end of a struct */ w = SZ_LONG; + if(packflg) + w = packflg; break; case Ael1: /* initial allign of struct element */ @@ -668,6 +551,8 @@ align(long i, Type *t, int op) w = ewidth[v->etype]; if(w <= 0 || w >= SZ_LONG) w = SZ_LONG; + if(packflg) + w = packflg; break; case Ael2: /* width of a struct element */ @@ -687,7 +572,8 @@ align(long i, Type *t, int op) w = SZ_LONG; break; } - o += SZ_LONG - w; /* big endian adjustment */ + if(thechar == 'v') + o += SZ_LONG - w; /* big endian adjustment */ w = 1; break; |
