diff options
Diffstat (limited to 'src/cmd/cc/sub.c')
-rw-r--r-- | src/cmd/cc/sub.c | 2068 |
1 files changed, 0 insertions, 2068 deletions
diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c deleted file mode 100644 index 94c11d021..000000000 --- a/src/cmd/cc/sub.c +++ /dev/null @@ -1,2068 +0,0 @@ -// Inferno utils/cc/sub.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/sub.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include <u.h> -#include "cc.h" - -Node* -new(int t, Node *l, Node *r) -{ - Node *n; - - n = alloc(sizeof(*n)); - n->op = t; - n->left = l; - n->right = r; - if(l && t != OGOTO) - n->lineno = l->lineno; - else if(r) - n->lineno = r->lineno; - else - n->lineno = lineno; - newflag = 1; - return n; -} - -Node* -new1(int o, Node *l, Node *r) -{ - Node *n; - - n = new(o, l, r); - n->lineno = nearln; - return n; -} - -void -prtree(Node *n, char *s) -{ - - print(" == %s ==\n", s); - prtree1(n, 0, 0); - print("\n"); -} - -void -prtree1(Node *n, int d, int f) -{ - int i; - - if(f) - for(i=0; i<d; i++) - print(" "); - if(n == Z) { - print("Z\n"); - return; - } - if(n->op == OLIST) { - prtree1(n->left, d, 0); - prtree1(n->right, d, 1); - return; - } - d++; - print("%O", n->op); - i = 3; - switch(n->op) - { - case ONAME: - print(" \"%F\"", n); - print(" %d", n->xoffset); - i = 0; - break; - - case OINDREG: - print(" %d(R%d)", n->xoffset, n->reg); - i = 0; - break; - - case OREGISTER: - if(n->xoffset) - print(" %d+R%d", n->xoffset, n->reg); - else - print(" R%d", n->reg); - i = 0; - break; - - case OSTRING: - print(" \"%s\"", n->cstring); - i = 0; - break; - - case OLSTRING: - if(sizeof(TRune) == sizeof(Rune)) - print(" \"%S\"", (Rune*)n->rstring); - else - print(" \"...\""); - i = 0; - break; - - case ODOT: - case OELEM: - print(" \"%F\"", n); - break; - - case OCONST: - if(typefd[n->type->etype]) - print(" \"%.8e\"", n->fconst); - else - print(" \"%lld\"", n->vconst); - i = 0; - break; - } - if(n->addable != 0) - print(" <%d>", n->addable); - if(n->type != T) - print(" %T", n->type); - if(n->complex != 0) - print(" (%d)", n->complex); - print(" %L\n", n->lineno); - if(i & 2) - prtree1(n->left, d, 1); - if(i & 1) - prtree1(n->right, d, 1); -} - -Type* -typ(int et, Type *d) -{ - Type *t; - - t = alloc(sizeof(*t)); - t->etype = et; - t->link = d; - t->down = T; - t->sym = S; - if(et < NTYPE) - t->width = ewidth[et]; - else - t->width = -1; // for TDOT or TOLD in prototype - t->offset = 0; - t->shift = 0; - t->nbits = 0; - t->garb = 0; - return t; -} - -Type* -copytyp(Type *t) -{ - Type *nt; - - nt = typ(TXXX, T); - *nt = *t; - return nt; -} - -Type* -garbt(Type *t, int32 b) -{ - Type *t1; - - if(b & BGARB) { - t1 = copytyp(t); - t1->garb = simpleg(b); - return t1; - } - return t; -} - -int -simpleg(int32 b) -{ - - b &= BGARB; - switch(b) { - case BCONSTNT: - return GCONSTNT; - case BVOLATILE: - return GVOLATILE; - case BVOLATILE|BCONSTNT: - return GCONSTNT|GVOLATILE; - } - return GXXX; -} - -int -simplec(int32 b) -{ - - b &= BCLASS; - switch(b) { - case 0: - case BREGISTER: - return CXXX; - case BAUTO: - case BAUTO|BREGISTER: - return CAUTO; - case BEXTERN: - return CEXTERN; - case BEXTERN|BREGISTER: - return CEXREG; - case BSTATIC: - return CSTATIC; - case BTYPEDEF: - return CTYPEDEF; - case BTYPESTR: - return CTYPESTR; - } - diag(Z, "illegal combination of classes %Q", b); - return CXXX; -} - -Type* -simplet(int32 b) -{ - - b &= ~BCLASS & ~BGARB; - switch(b) { - case BCHAR: - case BCHAR|BSIGNED: - return types[TCHAR]; - - case BCHAR|BUNSIGNED: - return types[TUCHAR]; - - case BSHORT: - case BSHORT|BINT: - case BSHORT|BSIGNED: - case BSHORT|BINT|BSIGNED: - return types[TSHORT]; - - case BUNSIGNED|BSHORT: - case BUNSIGNED|BSHORT|BINT: - return types[TUSHORT]; - - case 0: - case BINT: - case BINT|BSIGNED: - case BSIGNED: - return types[TINT]; - - case BUNSIGNED: - case BUNSIGNED|BINT: - return types[TUINT]; - - case BLONG: - case BLONG|BINT: - case BLONG|BSIGNED: - case BLONG|BINT|BSIGNED: - return types[TLONG]; - - case BUNSIGNED|BLONG: - case BUNSIGNED|BLONG|BINT: - return types[TULONG]; - - case BVLONG|BLONG: - case BVLONG|BLONG|BINT: - case BVLONG|BLONG|BSIGNED: - case BVLONG|BLONG|BINT|BSIGNED: - return types[TVLONG]; - - case BVLONG|BLONG|BUNSIGNED: - case BVLONG|BLONG|BINT|BUNSIGNED: - return types[TUVLONG]; - - case BFLOAT: - return types[TFLOAT]; - - case BDOUBLE: - case BDOUBLE|BLONG: - case BFLOAT|BLONG: - return types[TDOUBLE]; - - case BVOID: - return types[TVOID]; - } - - diag(Z, "illegal combination of types %Q", b); - return types[TINT]; -} - -int -stcompat(Node *n, Type *t1, Type *t2, int32 ttab[]) -{ - int i; - uint32 b; - - i = 0; - if(t2 != T) - i = t2->etype; - b = 1L << i; - i = 0; - if(t1 != T) - i = t1->etype; - if(b & ttab[i]) { - if(ttab == tasign) - if(b == BSTRUCT || b == BUNION) - if(!sametype(t1, t2)) - return 1; - if(n->op != OCAST) - if(b == BIND && i == TIND) - if(!sametype(t1, t2)) - return 1; - return 0; - } - return 1; -} - -int -tcompat(Node *n, Type *t1, Type *t2, int32 ttab[]) -{ - - if(stcompat(n, t1, t2, ttab)) { - if(t1 == T) - diag(n, "incompatible type: \"%T\" for op \"%O\"", - t2, n->op); - else - diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"", - t1, t2, n->op); - return 1; - } - return 0; -} - -void -makedot(Node *n, Type *t, int32 o) -{ - Node *n1, *n2; - - if(t->nbits) { - n1 = new(OXXX, Z, Z); - *n1 = *n; - n->op = OBIT; - n->left = n1; - n->right = Z; - n->type = t; - n->addable = n1->left->addable; - n = n1; - } - n->addable = n->left->addable; - if(n->addable == 0) { - n1 = new1(OCONST, Z, Z); - n1->vconst = o; - n1->type = types[TLONG]; - n->right = n1; - n->type = t; - return; - } - n->left->type = t; - if(o == 0) { - *n = *n->left; - return; - } - n->type = t; - n1 = new1(OCONST, Z, Z); - n1->vconst = o; - t = typ(TIND, t); - t->width = types[TIND]->width; - n1->type = t; - - n2 = new1(OADDR, n->left, Z); - n2->type = t; - - n1 = new1(OADD, n1, n2); - n1->type = t; - - n->op = OIND; - n->left = n1; - n->right = Z; -} - -Type* -dotsearch(Sym *s, Type *t, Node *n, int32 *off) -{ - Type *t1, *xt, *rt; - - xt = T; - - /* - * look it up by name - */ - for(t1 = t; t1 != T; t1 = t1->down) - if(t1->sym == s) { - if(xt != T) - goto ambig; - xt = t1; - } - - /* - * look it up by type - */ - if(s->class == CTYPEDEF || s->class == CTYPESTR) - for(t1 = t; t1 != T; t1 = t1->down) - if(t1->sym == S && typesu[t1->etype]) - if(sametype(s->type, t1)) { - if(xt != T) - goto ambig; - xt = t1; - } - if(xt != T) { - *off = xt->offset; - return xt; - } - - /* - * look it up in unnamed substructures - */ - for(t1 = t; t1 != T; t1 = t1->down) - if(t1->sym == S && typesu[t1->etype]){ - rt = dotsearch(s, t1->link, n, off); - if(rt != T) { - if(xt != T) - goto ambig; - xt = rt; - *off += t1->offset; - } - } - return xt; - -ambig: - diag(n, "ambiguous structure element: %s", s->name); - return xt; -} - -int32 -dotoffset(Type *st, Type *lt, Node *n) -{ - Type *t; - Sym *g; - int32 o, o1; - - o = -1; - /* - * first try matching at the top level - * for matching tag names - */ - g = st->tag; - if(g != S) - for(t=lt->link; t!=T; t=t->down) - if(t->sym == S) - if(g == t->tag) { - if(o >= 0) - goto ambig; - o = t->offset; - } - if(o >= 0) - return o; - - /* - * second try matching at the top level - * for similar types - */ - for(t=lt->link; t!=T; t=t->down) - if(t->sym == S) - if(sametype(st, t)) { - if(o >= 0) - goto ambig; - o = t->offset; - } - if(o >= 0) - return o; - - /* - * last try matching sub-levels - */ - for(t=lt->link; t!=T; t=t->down) - if(t->sym == S) - if(typesu[t->etype]) { - o1 = dotoffset(st, t, n); - if(o1 >= 0) { - if(o >= 0) - goto ambig; - o = o1 + t->offset; - } - } - return o; - -ambig: - diag(n, "ambiguous unnamed structure element"); - return o; -} - -/* - * look into tree for floating point constant expressions - */ -int -allfloat(Node *n, int flag) -{ - - if(n != Z) { - if(n->type->etype != TDOUBLE) - return 1; - switch(n->op) { - case OCONST: - if(flag) - n->type = types[TFLOAT]; - return 1; - case OADD: /* no need to get more exotic than this */ - case OSUB: - case OMUL: - case ODIV: - if(!allfloat(n->right, flag)) - break; - case OCAST: - if(!allfloat(n->left, flag)) - break; - if(flag) - n->type = types[TFLOAT]; - return 1; - } - } - return 0; -} - -void -constas(Node *n, Type *il, Type *ir) -{ - Type *l, *r; - - l = il; - r = ir; - - if(l == T) - return; - if(l->garb & GCONSTNT) { - warn(n, "assignment to a constant type (%T)", il); - return; - } - if(r == T) - return; - for(;;) { - if(l->etype != TIND || r->etype != TIND) - break; - l = l->link; - r = r->link; - if(l == T || r == T) - break; - if(r->garb & GCONSTNT) - if(!(l->garb & GCONSTNT)) { - warn(n, "assignment of a constant pointer type (%T)", ir); - break; - } - } -} - -void -typeext1(Type *st, Node *l) -{ - if(st->etype == TFLOAT && allfloat(l, 0)) - allfloat(l, 1); -} - -void -typeext(Type *st, Node *l) -{ - Type *lt; - Node *n1, *n2; - int32 o; - - lt = l->type; - if(lt == T) - return; - if(st->etype == TIND && vconst(l) == 0) { - l->type = st; - l->vconst = 0; - return; - } - typeext1(st, l); - - /* - * extension of C - * if assign of struct containing unnamed sub-struct - * to type of sub-struct, insert the DOT. - * if assign of *struct containing unnamed substruct - * to type of *sub-struct, insert the add-offset - */ - if(typesu[st->etype] && typesu[lt->etype]) { - o = dotoffset(st, lt, l); - if(o >= 0) { - n1 = new1(OXXX, Z, Z); - *n1 = *l; - l->op = ODOT; - l->left = n1; - l->right = Z; - makedot(l, st, o); - } - return; - } - if(st->etype == TIND && typesu[st->link->etype]) - if(lt->etype == TIND && typesu[lt->link->etype]) { - o = dotoffset(st->link, lt->link, l); - if(o >= 0) { - l->type = st; - if(o == 0) - return; - n1 = new1(OXXX, Z, Z); - *n1 = *l; - n2 = new1(OCONST, Z, Z); - n2->vconst = o; - n2->type = st; - l->op = OADD; - l->left = n1; - l->right = n2; - } - return; - } -} - -/* - * a cast that generates no code - * (same size move) - */ -int -nocast(Type *t1, Type *t2) -{ - int i, b; - - if(t1->nbits) - return 0; - i = 0; - if(t2 != T) - i = t2->etype; - b = 1<<i; - i = 0; - if(t1 != T) - i = t1->etype; - if(b & ncast[i]) - return 1; - return 0; -} - -/* - * a cast that has a noop semantic - * (small to large, convert) - */ -int -nilcast(Type *t1, Type *t2) -{ - int et1, et2; - - if(t1 == T) - return 0; - if(t1->nbits) - return 0; - if(t2 == T) - return 0; - et1 = t1->etype; - et2 = t2->etype; - if(et1 == et2) - return 1; - if(typefd[et1] && typefd[et2]) { - if(ewidth[et1] < ewidth[et2]) - return 1; - return 0; - } - if(typechlp[et1] && typechlp[et2]) { - if(ewidth[et1] < ewidth[et2]) - return 1; - return 0; - } - return 0; -} - -/* - * "the usual arithmetic conversions are performed" - */ -void -arith(Node *n, int f) -{ - Type *t1, *t2; - int i, j, k; - Node *n1; - int32 w; - - t1 = n->left->type; - if(n->right == Z) - t2 = t1; - else - t2 = n->right->type; - i = TXXX; - if(t1 != T) - i = t1->etype; - j = TXXX; - if(t2 != T) - j = t2->etype; - k = tab[i][j]; - if(k == TIND) { - if(i == TIND) - n->type = t1; - else - if(j == TIND) - n->type = t2; - } else { - /* convert up to at least int */ - if(f == 1) - while(k < TINT) - k += 2; - n->type = types[k]; - } - if(n->op == OSUB) - if(i == TIND && j == TIND) { - w = n->right->type->link->width; - if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1) - goto bad; - n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG]; - if(0 && ewidth[TIND] > ewidth[TLONG]){ - n1 = new1(OXXX, Z, Z); - *n1 = *n; - n->op = OCAST; - n->left = n1; - n->right = Z; - n->type = types[TLONG]; - } - if(w > 1) { - n1 = new1(OXXX, Z, Z); - *n1 = *n; - n->op = ODIV; - n->left = n1; - n1 = new1(OCONST, Z, Z); - n1->vconst = w; - n1->type = n->type; - n->right = n1; - w = vlog(n1); - if(w >= 0) { - n->op = OASHR; - n1->vconst = w; - } - } - return; - } - if(!sametype(n->type, n->left->type)) { - n->left = new1(OCAST, n->left, Z); - n->left->type = n->type; - if(n->type->etype == TIND) { - w = n->type->link->width; - if(w < 1) { - snap(n->type->link); - w = n->type->link->width; - if(w < 1) - goto bad; - } - if(w > 1) { - n1 = new1(OCONST, Z, Z); - n1->vconst = w; - n1->type = n->type; - n->left = new1(OMUL, n->left, n1); - n->left->type = n->type; - } - } - } - if(n->right != Z) - if(!sametype(n->type, n->right->type)) { - n->right = new1(OCAST, n->right, Z); - n->right->type = n->type; - if(n->type->etype == TIND) { - w = n->type->link->width; - if(w < 1) { - snap(n->type->link); - w = n->type->link->width; - if(w < 1) - goto bad; - } - if(w != 1) { - n1 = new1(OCONST, Z, Z); - n1->vconst = w; - n1->type = n->type; - n->right = new1(OMUL, n->right, n1); - n->right->type = n->type; - } - } - } - return; -bad: - diag(n, "pointer addition not fully declared: %T", n->type->link); -} - -/* - * try to rewrite shift & mask - */ -void -simplifyshift(Node *n) -{ - uint32 c3; - int o, s1, s2, c1, c2; - - if(!typechlp[n->type->etype]) - return; - switch(n->op) { - default: - return; - case OASHL: - s1 = 0; - break; - case OLSHR: - s1 = 1; - break; - case OASHR: - s1 = 2; - break; - } - if(n->right->op != OCONST) - return; - if(n->left->op != OAND) - return; - if(n->left->right->op != OCONST) - return; - switch(n->left->left->op) { - default: - return; - case OASHL: - s2 = 0; - break; - case OLSHR: - s2 = 1; - break; - case OASHR: - s2 = 2; - break; - } - if(n->left->left->right->op != OCONST) - return; - - c1 = n->right->vconst; - c2 = n->left->left->right->vconst; - c3 = n->left->right->vconst; - - o = n->op; - switch((s1<<3)|s2) { - case 000: /* (((e <<u c2) & c3) <<u c1) */ - c3 >>= c2; - c1 += c2; - if(c1 >= 32) - break; - goto rewrite1; - - case 002: /* (((e >>s c2) & c3) <<u c1) */ - if(topbit(c3) >= (32-c2)) - break; - case 001: /* (((e >>u c2) & c3) <<u c1) */ - if(c1 > c2) { - c3 <<= c2; - c1 -= c2; - o = OASHL; - goto rewrite1; - } - c3 <<= c1; - if(c1 == c2) - goto rewrite0; - c1 = c2-c1; - o = OLSHR; - goto rewrite2; - - case 022: /* (((e >>s c2) & c3) >>s c1) */ - if(c2 <= 0) - break; - case 012: /* (((e >>s c2) & c3) >>u c1) */ - if(topbit(c3) >= (32-c2)) - break; - goto s11; - case 021: /* (((e >>u c2) & c3) >>s c1) */ - if(topbit(c3) >= 31 && c2 <= 0) - break; - goto s11; - case 011: /* (((e >>u c2) & c3) >>u c1) */ - s11: - c3 <<= c2; - c1 += c2; - if(c1 >= 32) - break; - o = OLSHR; - goto rewrite1; - - case 020: /* (((e <<u c2) & c3) >>s c1) */ - if(topbit(c3) >= 31) - break; - case 010: /* (((e <<u c2) & c3) >>u c1) */ - c3 >>= c1; - if(c1 == c2) - goto rewrite0; - if(c1 > c2) { - c1 -= c2; - goto rewrite2; - } - c1 = c2 - c1; - o = OASHL; - goto rewrite2; - } - return; - -rewrite0: /* get rid of both shifts */ -if(debug['<'])prtree(n, "rewrite0"); - *n = *n->left; - n->left = n->left->left; - n->right->vconst = c3; - return; -rewrite1: /* get rid of lower shift */ -if(debug['<'])prtree(n, "rewrite1"); - n->left->left = n->left->left->left; - n->left->right->vconst = c3; - n->right->vconst = c1; - n->op = o; - return; -rewrite2: /* get rid of upper shift */ -if(debug['<'])prtree(n, "rewrite2"); - *n = *n->left; - n->right->vconst = c3; - n->left->right->vconst = c1; - n->left->op = o; -} - -int -side(Node *n) -{ - -loop: - if(n != Z) - switch(n->op) { - case OCAST: - case ONOT: - case OADDR: - case OIND: - n = n->left; - goto loop; - - case OCOND: - if(side(n->left)) - break; - n = n->right; - - case OEQ: - case ONE: - case OLT: - case OGE: - case OGT: - case OLE: - case OADD: - case OSUB: - case OMUL: - case OLMUL: - case ODIV: - case OLDIV: - case OLSHR: - case OASHL: - case OASHR: - case OAND: - case OOR: - case OXOR: - case OMOD: - case OLMOD: - case OANDAND: - case OOROR: - case OCOMMA: - case ODOT: - if(side(n->left)) - break; - n = n->right; - goto loop; - - case OSIGN: - case OSIZE: - case OCONST: - case OSTRING: - case OLSTRING: - case ONAME: - return 0; - } - return 1; -} - -int -vconst(Node *n) -{ - int i; - - if(n == Z) - goto no; - if(n->op != OCONST) - goto no; - if(n->type == T) - goto no; - switch(n->type->etype) - { - case TFLOAT: - case TDOUBLE: - i = 100; - if(n->fconst > i || n->fconst < -i) - goto no; - i = n->fconst; - if(i != n->fconst) - goto no; - return i; - - case TVLONG: - case TUVLONG: - i = n->vconst; - if(i != n->vconst) - goto no; - return i; - - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - i = n->vconst; - if(i != n->vconst) - goto no; - return i; - } -no: - return -159; /* first uninteresting constant */ -} - -/* - * return log(n) if n is a power of 2 constant - */ -int -xlog2(uvlong v) -{ - int s, i; - uvlong m; - - s = 0; - m = MASK(8*sizeof(uvlong)); - for(i=32; i; i>>=1) { - m >>= i; - if(!(v & m)) { - v >>= i; - s += i; - } - } - if(v == 1) - return s; - return -1; -} - -int -vlog(Node *n) -{ - if(n->op != OCONST) - goto bad; - if(typefd[n->type->etype]) - goto bad; - - return xlog2(n->vconst); - -bad: - return -1; -} - -int -topbit(uint32 v) -{ - int i; - - for(i = -1; v; i++) - v >>= 1; - return i; -} - -/* - * try to cast a constant down - * rather than cast a variable up - * example: - * if(c == 'a') - */ -void -relcon(Node *l, Node *r) -{ - vlong v; - - if(l->op != OCONST) - return; - if(r->op != OCAST) - return; - if(!nilcast(r->left->type, r->type)) - return; - switch(r->type->etype) { - default: - return; - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - v = convvtox(l->vconst, r->type->etype); - if(v != l->vconst) - return; - break; - } - l->type = r->left->type; - *r = *r->left; -} - -int -relindex(int o) -{ - - switch(o) { - default: - diag(Z, "bad in relindex: %O", o); - case OEQ: return 0; - case ONE: return 1; - case OLE: return 2; - case OLS: return 3; - case OLT: return 4; - case OLO: return 5; - case OGE: return 6; - case OHS: return 7; - case OGT: return 8; - case OHI: return 9; - } -} - -Node* -invert(Node *n) -{ - Node *i; - - if(n == Z || n->op != OLIST) - return n; - i = n; - for(n = n->left; n != Z; n = n->left) { - if(n->op != OLIST) - break; - i->left = n->right; - n->right = i; - i = n; - } - i->left = n; - return i; -} - -int -bitno(int32 b) -{ - int i; - - for(i=0; i<32; i++) - if(b & (1L<<i)) - return i; - diag(Z, "bad in bitno"); - return 0; -} - -int32 -typebitor(int32 a, int32 b) -{ - int32 c; - - c = a | b; - if(a & b) - if((a & b) == BLONG) - c |= BVLONG; /* long long => vlong */ - else - warn(Z, "once is enough: %Q", a & b); - return c; -} - -void -diag(Node *n, char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); - - if(debug['X']){ - Bflush(&diagbuf); - abort(); - } - if(n != Z) - if(debug['v']) - prtree(n, "diagnostic"); - - nerrors++; - if(nerrors > 10) { - Bprint(&diagbuf, "too many errors\n"); - errorexit(); - } -} - -void -warn(Node *n, char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - if(debug['w']) { - Bprint(&diagbuf, "warning: "); - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); - - if(n != Z) - if(debug['v']) - prtree(n, "warning"); - } -} - -void -yyerror(char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - /* - * hack to intercept message from yaccpar - */ - if(strcmp(fmt, "syntax error") == 0) { - yyerror("syntax error, last name: %s", symb); - return; - } - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", lineno, buf); - nerrors++; - if(nerrors > 10) { - Bprint(&diagbuf, "too many errors\n"); - errorexit(); - } -} - -void -fatal(Node *n, char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); - - if(debug['X']){ - Bflush(&diagbuf); - abort(); - } - if(n != Z) - if(debug['v']) - prtree(n, "diagnostic"); - - nerrors++; - errorexit(); -} - -uint32 thash1 = 0x2edab8c9; -uint32 thash2 = 0x1dc74fb8; -uint32 thash3 = 0x1f241331; -uint32 thash[NALLTYPES]; -Init thashinit[] = -{ - TXXX, 0x17527bbd, 0, - TCHAR, 0x5cedd32b, 0, - TUCHAR, 0x552c4454, 0, - TSHORT, 0x63040b4b, 0, - TUSHORT, 0x32a45878, 0, - TINT, 0x4151d5bd, 0, - TUINT, 0x5ae707d6, 0, - TLONG, 0x5ef20f47, 0, - TULONG, 0x36d8eb8f, 0, - TVLONG, 0x6e5e9590, 0, - TUVLONG, 0x75910105, 0, - TFLOAT, 0x25fd7af1, 0, - TDOUBLE, 0x7c40a1b2, 0, - TIND, 0x1b832357, 0, - TFUNC, 0x6babc9cb, 0, - TARRAY, 0x7c50986d, 0, - TVOID, 0x44112eff, 0, - TSTRUCT, 0x7c2da3bf, 0, - TUNION, 0x3eb25e98, 0, - TENUM, 0x44b54f61, 0, - TFILE, 0x19242ac3, 0, - TOLD, 0x22b15988, 0, - TDOT, 0x0204f6b3, 0, - -1, 0, 0, -}; - -char* bnames[NALIGN]; -Init bnamesinit[] = -{ - Axxx, 0, "Axxx", - Ael1, 0, "el1", - Ael2, 0, "el2", - Asu2, 0, "su2", - Aarg0, 0, "arg0", - Aarg1, 0, "arg1", - Aarg2, 0, "arg2", - Aaut3, 0, "aut3", - -1, 0, 0, -}; - -char* tnames[NALLTYPES]; -Init tnamesinit[] = -{ - TXXX, 0, "TXXX", - TCHAR, 0, "CHAR", - TUCHAR, 0, "UCHAR", - TSHORT, 0, "SHORT", - TUSHORT, 0, "USHORT", - TINT, 0, "INT", - TUINT, 0, "UINT", - TLONG, 0, "LONG", - TULONG, 0, "ULONG", - TVLONG, 0, "VLONG", - TUVLONG, 0, "UVLONG", - TFLOAT, 0, "FLOAT", - TDOUBLE, 0, "DOUBLE", - TIND, 0, "IND", - TFUNC, 0, "FUNC", - TARRAY, 0, "ARRAY", - TVOID, 0, "VOID", - TSTRUCT, 0, "STRUCT", - TUNION, 0, "UNION", - TENUM, 0, "ENUM", - TFILE, 0, "FILE", - TOLD, 0, "OLD", - TDOT, 0, "DOT", - -1, 0, 0, -}; - -char* gnames[NGTYPES]; -Init gnamesinit[] = -{ - GXXX, 0, "GXXX", - GCONSTNT, 0, "CONST", - GVOLATILE, 0, "VOLATILE", - GVOLATILE|GCONSTNT, 0, "CONST-VOLATILE", - -1, 0, 0, -}; - -char* qnames[NALLTYPES]; -Init qnamesinit[] = -{ - TXXX, 0, "TXXX", - TCHAR, 0, "CHAR", - TUCHAR, 0, "UCHAR", - TSHORT, 0, "SHORT", - TUSHORT, 0, "USHORT", - TINT, 0, "INT", - TUINT, 0, "UINT", - TLONG, 0, "LONG", - TULONG, 0, "ULONG", - TVLONG, 0, "VLONG", - TUVLONG, 0, "UVLONG", - TFLOAT, 0, "FLOAT", - TDOUBLE, 0, "DOUBLE", - TIND, 0, "IND", - TFUNC, 0, "FUNC", - TARRAY, 0, "ARRAY", - TVOID, 0, "VOID", - TSTRUCT, 0, "STRUCT", - TUNION, 0, "UNION", - TENUM, 0, "ENUM", - - TAUTO, 0, "AUTO", - TEXTERN, 0, "EXTERN", - TSTATIC, 0, "STATIC", - TTYPEDEF, 0, "TYPEDEF", - TTYPESTR, 0, "TYPESTR", - TREGISTER, 0, "REGISTER", - TCONSTNT, 0, "CONSTNT", - TVOLATILE, 0, "VOLATILE", - TUNSIGNED, 0, "UNSIGNED", - TSIGNED, 0, "SIGNED", - TDOT, 0, "DOT", - TFILE, 0, "FILE", - TOLD, 0, "OLD", - -1, 0, 0, -}; -char* cnames[NCTYPES]; -Init cnamesinit[] = -{ - CXXX, 0, "CXXX", - CAUTO, 0, "AUTO", - CEXTERN, 0, "EXTERN", - CGLOBL, 0, "GLOBL", - CSTATIC, 0, "STATIC", - CLOCAL, 0, "LOCAL", - CTYPEDEF, 0, "TYPEDEF", - CTYPESTR, 0, "TYPESTR", - CPARAM, 0, "PARAM", - CSELEM, 0, "SELEM", - CLABEL, 0, "LABEL", - CEXREG, 0, "EXREG", - -1, 0, 0, -}; - -char* onames[OEND+1]; -Init onamesinit[] = -{ - OXXX, 0, "OXXX", - OADD, 0, "ADD", - OADDR, 0, "ADDR", - OAND, 0, "AND", - OANDAND, 0, "ANDAND", - OARRAY, 0, "ARRAY", - OAS, 0, "AS", - OASI, 0, "ASI", - OASADD, 0, "ASADD", - OASAND, 0, "ASAND", - OASASHL, 0, "ASASHL", - OASASHR, 0, "ASASHR", - OASDIV, 0, "ASDIV", - OASHL, 0, "ASHL", - OASHR, 0, "ASHR", - OASLDIV, 0, "ASLDIV", - OASLMOD, 0, "ASLMOD", - OASLMUL, 0, "ASLMUL", - OASLSHR, 0, "ASLSHR", - OASMOD, 0, "ASMOD", - OASMUL, 0, "ASMUL", - OASOR, 0, "ASOR", - OASSUB, 0, "ASSUB", - OASXOR, 0, "ASXOR", - OBIT, 0, "BIT", - OBREAK, 0, "BREAK", - OCASE, 0, "CASE", - OCAST, 0, "CAST", - OCOMMA, 0, "COMMA", - OCOND, 0, "COND", - OCONST, 0, "CONST", - OCONTINUE, 0, "CONTINUE", - ODIV, 0, "DIV", - ODOT, 0, "DOT", - ODOTDOT, 0, "DOTDOT", - ODWHILE, 0, "DWHILE", - OENUM, 0, "ENUM", - OEQ, 0, "EQ", - OEXREG, 0, "EXREG", - OFOR, 0, "FOR", - OFUNC, 0, "FUNC", - OGE, 0, "GE", - OGOTO, 0, "GOTO", - OGT, 0, "GT", - OHI, 0, "HI", - OHS, 0, "HS", - OIF, 0, "IF", - OIND, 0, "IND", - OINDREG, 0, "INDREG", - OINIT, 0, "INIT", - OLABEL, 0, "LABEL", - OLDIV, 0, "LDIV", - OLE, 0, "LE", - OLIST, 0, "LIST", - OLMOD, 0, "LMOD", - OLMUL, 0, "LMUL", - OLO, 0, "LO", - OLS, 0, "LS", - OLSHR, 0, "LSHR", - OLT, 0, "LT", - OMOD, 0, "MOD", - OMUL, 0, "MUL", - ONAME, 0, "NAME", - ONE, 0, "NE", - ONOT, 0, "NOT", - OOR, 0, "OR", - OOROR, 0, "OROR", - OPOSTDEC, 0, "POSTDEC", - OPOSTINC, 0, "POSTINC", - OPREDEC, 0, "PREDEC", - OPREINC, 0, "PREINC", - OPREFETCH, 0, "PREFETCH", - OPROTO, 0, "PROTO", - OREGISTER, 0, "REGISTER", - ORETURN, 0, "RETURN", - OSET, 0, "SET", - OSIGN, 0, "SIGN", - OSIZE, 0, "SIZE", - OSTRING, 0, "STRING", - OLSTRING, 0, "LSTRING", - OSTRUCT, 0, "STRUCT", - OSUB, 0, "SUB", - OSWITCH, 0, "SWITCH", - OUNION, 0, "UNION", - OUSED, 0, "USED", - OWHILE, 0, "WHILE", - OXOR, 0, "XOR", - OPOS, 0, "POS", - ONEG, 0, "NEG", - OCOM, 0, "COM", - OELEM, 0, "ELEM", - OTST, 0, "TST", - OINDEX, 0, "INDEX", - OFAS, 0, "FAS", - OREGPAIR, 0, "REGPAIR", - OROTL, 0, "ROTL", - OEND, 0, "END", - -1, 0, 0, -}; - -/* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */ -uchar comrel[12] = -{ - ONE, OEQ, OGT, OHI, OGE, OHS, OLT, OLO, OLE, OLS, -}; -uchar invrel[12] = -{ - OEQ, ONE, OGE, OHS, OGT, OHI, OLE, OLS, OLT, OLO, -}; -uchar logrel[12] = -{ - OEQ, ONE, OLS, OLS, OLO, OLO, OHS, OHS, OHI, OHI, -}; - -uchar typei[NALLTYPES]; -int typeiinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TVLONG, TUVLONG, -1, -}; -uchar typeu[NALLTYPES]; -int typeuinit[] = -{ - TUCHAR, TUSHORT, TUINT, TULONG, TUVLONG, TIND, -1, -}; - -uchar typesuv[NALLTYPES]; -int typesuvinit[] = -{ - TVLONG, TUVLONG, TSTRUCT, TUNION, -1, -}; - -uchar typeilp[NALLTYPES]; -int typeilpinit[] = -{ - TINT, TUINT, TLONG, TULONG, TIND, -1 -}; - -uchar typechl[NALLTYPES]; -uchar typechlv[NALLTYPES]; -uchar typechlvp[NALLTYPES]; -int typechlinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1, -}; - -uchar typechlp[NALLTYPES]; -int typechlpinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TIND, -1, -}; - -uchar typechlpfd[NALLTYPES]; -int typechlpfdinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TIND, -1, -}; - -uchar typec[NALLTYPES]; -int typecinit[] = -{ - TCHAR, TUCHAR, -1 -}; - -uchar typeh[NALLTYPES]; -int typehinit[] = -{ - TSHORT, TUSHORT, -1, -}; - -uchar typeil[NALLTYPES]; -int typeilinit[] = -{ - TINT, TUINT, TLONG, TULONG, -1, -}; - -uchar typev[NALLTYPES]; -int typevinit[] = -{ - TVLONG, TUVLONG, -1, -}; - -uchar typefd[NALLTYPES]; -int typefdinit[] = -{ - TFLOAT, TDOUBLE, -1, -}; - -uchar typeaf[NALLTYPES]; -int typeafinit[] = -{ - TFUNC, TARRAY, -1, -}; - -uchar typesu[NALLTYPES]; -int typesuinit[] = -{ - TSTRUCT, TUNION, -1, -}; - -int32 tasign[NALLTYPES]; -Init tasigninit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BIND, 0, - TSTRUCT, BSTRUCT, 0, - TUNION, BUNION, 0, - -1, 0, 0, -}; - -int32 tasadd[NALLTYPES]; -Init tasaddinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BINTEGER, 0, - -1, 0, 0, -}; - -int32 tcast[NALLTYPES]; -Init tcastinit[] = -{ - TCHAR, BNUMBER|BIND|BVOID, 0, - TUCHAR, BNUMBER|BIND|BVOID, 0, - TSHORT, BNUMBER|BIND|BVOID, 0, - TUSHORT, BNUMBER|BIND|BVOID, 0, - TINT, BNUMBER|BIND|BVOID, 0, - TUINT, BNUMBER|BIND|BVOID, 0, - TLONG, BNUMBER|BIND|BVOID, 0, - TULONG, BNUMBER|BIND|BVOID, 0, - TVLONG, BNUMBER|BIND|BVOID, 0, - TUVLONG, BNUMBER|BIND|BVOID, 0, - TFLOAT, BNUMBER|BVOID, 0, - TDOUBLE, BNUMBER|BVOID, 0, - TIND, BINTEGER|BIND|BVOID, 0, - TVOID, BVOID, 0, - TSTRUCT, BSTRUCT|BVOID, 0, - TUNION, BUNION|BVOID, 0, - -1, 0, 0, -}; - -int32 tadd[NALLTYPES]; -Init taddinit[] = -{ - TCHAR, BNUMBER|BIND, 0, - TUCHAR, BNUMBER|BIND, 0, - TSHORT, BNUMBER|BIND, 0, - TUSHORT, BNUMBER|BIND, 0, - TINT, BNUMBER|BIND, 0, - TUINT, BNUMBER|BIND, 0, - TLONG, BNUMBER|BIND, 0, - TULONG, BNUMBER|BIND, 0, - TVLONG, BNUMBER|BIND, 0, - TUVLONG, BNUMBER|BIND, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BINTEGER, 0, - -1, 0, 0, -}; - -int32 tsub[NALLTYPES]; -Init tsubinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BINTEGER|BIND, 0, - -1, 0, 0, -}; - -int32 tmul[NALLTYPES]; -Init tmulinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - -1, 0, 0, -}; - -int32 tand[NALLTYPES]; -Init tandinit[] = -{ - TCHAR, BINTEGER, 0, - TUCHAR, BINTEGER, 0, - TSHORT, BINTEGER, 0, - TUSHORT, BINTEGER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BINTEGER, 0, - TULONG, BINTEGER, 0, - TVLONG, BINTEGER, 0, - TUVLONG, BINTEGER, 0, - -1, 0, 0, -}; - -int32 trel[NALLTYPES]; -Init trelinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BIND, 0, - -1, 0, 0, -}; - -int32 tfunct[1] = -{ - BFUNC, -}; - -int32 tindir[1] = -{ - BIND, -}; - -int32 tdot[1] = -{ - BSTRUCT|BUNION, -}; - -int32 tnot[1] = -{ - BNUMBER|BIND, -}; - -int32 targ[1] = -{ - BNUMBER|BIND|BSTRUCT|BUNION, -}; - -uchar tab[NTYPE][NTYPE] = -{ -/*TXXX*/ { 0, - }, - -/*TCHAR*/ { 0, TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUCHAR*/ { 0, TUCHAR, TUCHAR, TUSHORT, TUSHORT, TUINT, TUINT, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TSHORT*/ { 0, TSHORT, TUSHORT, TSHORT, TUSHORT, TINT, TUINT, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUSHORT*/ { 0, TUSHORT, TUSHORT, TUSHORT, TUSHORT, TUINT, TUINT, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TINT*/ { 0, TINT, TUINT, TINT, TUINT, TINT, TUINT, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUINT*/ { 0, TUINT, TUINT, TUINT, TUINT, TUINT, TUINT, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TLONG*/ { 0, TLONG, TULONG, TLONG, TULONG, TLONG, TULONG, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TULONG*/ { 0, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TVLONG*/ { 0, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG, - TUVLONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUVLONG*/ { 0, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, - TUVLONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TFLOAT*/ { 0, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, - TFLOAT, TFLOAT, TFLOAT, TFLOAT, TDOUBLE, TIND, - }, -/*TDOUBLE*/ { 0, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, - TDOUBLE, TDOUBLE, TDOUBLE, TFLOAT, TDOUBLE, TIND, - }, -/*TIND*/ { 0, TIND, TIND, TIND, TIND, TIND, TIND, TIND, - TIND, TIND, TIND, TIND, TIND, TIND, - }, -}; - -void -urk(char *name, int max, int i) -{ - if(i >= max) { - fprint(2, "bad tinit: %s %d>=%d\n", name, i, max); - exits("init"); - } -} - -void -tinit(void) -{ - int *ip; - Init *p; - - for(p=thashinit; p->code >= 0; p++) { - urk("thash", nelem(thash), p->code); - thash[p->code] = p->value; - } - for(p=bnamesinit; p->code >= 0; p++) { - urk("bnames", nelem(bnames), p->code); - bnames[p->code] = p->s; - } - for(p=tnamesinit; p->code >= 0; p++) { - urk("tnames", nelem(tnames), p->code); - tnames[p->code] = p->s; - } - for(p=gnamesinit; p->code >= 0; p++) { - urk("gnames", nelem(gnames), p->code); - gnames[p->code] = p->s; - } - for(p=qnamesinit; p->code >= 0; p++) { - urk("qnames", nelem(qnames), p->code); - qnames[p->code] = p->s; - } - for(p=cnamesinit; p->code >= 0; p++) { - urk("cnames", nelem(cnames), p->code); - cnames[p->code] = p->s; - } - for(p=onamesinit; p->code >= 0; p++) { - urk("onames", nelem(onames), p->code); - onames[p->code] = p->s; - } - for(ip=typeiinit; *ip>=0; ip++) { - urk("typei", nelem(typei), *ip); - typei[*ip] = 1; - } - for(ip=typeuinit; *ip>=0; ip++) { - urk("typeu", nelem(typeu), *ip); - typeu[*ip] = 1; - } - for(ip=typesuvinit; *ip>=0; ip++) { - urk("typesuv", nelem(typesuv), *ip); - typesuv[*ip] = 1; - } - for(ip=typeilpinit; *ip>=0; ip++) { - urk("typeilp", nelem(typeilp), *ip); - typeilp[*ip] = 1; - } - for(ip=typechlinit; *ip>=0; ip++) { - urk("typechl", nelem(typechl), *ip); - typechl[*ip] = 1; - typechlv[*ip] = 1; - typechlvp[*ip] = 1; - } - for(ip=typechlpinit; *ip>=0; ip++) { - urk("typechlp", nelem(typechlp), *ip); - typechlp[*ip] = 1; - typechlvp[*ip] = 1; - } - for(ip=typechlpfdinit; *ip>=0; ip++) { - urk("typechlpfd", nelem(typechlpfd), *ip); - typechlpfd[*ip] = 1; - } - for(ip=typecinit; *ip>=0; ip++) { - urk("typec", nelem(typec), *ip); - typec[*ip] = 1; - } - for(ip=typehinit; *ip>=0; ip++) { - urk("typeh", nelem(typeh), *ip); - typeh[*ip] = 1; - } - for(ip=typeilinit; *ip>=0; ip++) { - urk("typeil", nelem(typeil), *ip); - typeil[*ip] = 1; - } - for(ip=typevinit; *ip>=0; ip++) { - urk("typev", nelem(typev), *ip); - typev[*ip] = 1; - typechlv[*ip] = 1; - typechlvp[*ip] = 1; - } - for(ip=typefdinit; *ip>=0; ip++) { - urk("typefd", nelem(typefd), *ip); - typefd[*ip] = 1; - } - for(ip=typeafinit; *ip>=0; ip++) { - urk("typeaf", nelem(typeaf), *ip); - typeaf[*ip] = 1; - } - for(ip=typesuinit; *ip >= 0; ip++) { - urk("typesu", nelem(typesu), *ip); - typesu[*ip] = 1; - } - for(p=tasigninit; p->code >= 0; p++) { - urk("tasign", nelem(tasign), p->code); - tasign[p->code] = p->value; - } - for(p=tasaddinit; p->code >= 0; p++) { - urk("tasadd", nelem(tasadd), p->code); - tasadd[p->code] = p->value; - } - for(p=tcastinit; p->code >= 0; p++) { - urk("tcast", nelem(tcast), p->code); - tcast[p->code] = p->value; - } - for(p=taddinit; p->code >= 0; p++) { - urk("tadd", nelem(tadd), p->code); - tadd[p->code] = p->value; - } - for(p=tsubinit; p->code >= 0; p++) { - urk("tsub", nelem(tsub), p->code); - tsub[p->code] = p->value; - } - for(p=tmulinit; p->code >= 0; p++) { - urk("tmul", nelem(tmul), p->code); - tmul[p->code] = p->value; - } - for(p=tandinit; p->code >= 0; p++) { - urk("tand", nelem(tand), p->code); - tand[p->code] = p->value; - } - for(p=trelinit; p->code >= 0; p++) { - urk("trel", nelem(trel), p->code); - trel[p->code] = p->value; - } - - /* 32-bit defaults */ - typeword = typechlp; - typecmplx = typesuv; -} - -/* - * return 1 if it is impossible to jump into the middle of n. - */ -static int -deadhead(Node *n, int caseok) -{ -loop: - if(n == Z) - return 1; - switch(n->op) { - case OLIST: - if(!deadhead(n->left, caseok)) - return 0; - rloop: - n = n->right; - goto loop; - - case ORETURN: - break; - - case OLABEL: - return 0; - - case OGOTO: - break; - - case OCASE: - if(!caseok) - return 0; - goto rloop; - - case OSWITCH: - return deadhead(n->right, 1); - - case OWHILE: - case ODWHILE: - goto rloop; - - case OFOR: - goto rloop; - - case OCONTINUE: - break; - - case OBREAK: - break; - - case OIF: - return deadhead(n->right->left, caseok) && deadhead(n->right->right, caseok); - - case OSET: - case OUSED: - break; - } - return 1; -} - -int -deadheads(Node *c) -{ - return deadhead(c->left, 0) && deadhead(c->right, 0); -} - -int -mixedasop(Type *l, Type *r) -{ - return !typefd[l->etype] && typefd[r->etype]; -} - -LSym* -linksym(Sym *s) -{ - if(s == nil) - return nil; - if(s->lsym != nil) - return s->lsym; - return linklookup(ctxt, s->name, s->class == CSTATIC); -} |