// 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	"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(" %ld", n->xoffset);
		i = 0;
		break;

	case OINDREG:
		print(" %ld(R%d)", n->xoffset, n->reg);
		i = 0;
		break;

	case OREGISTER:
		if(n->xoffset)
			print(" %ld+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:
		print(" \"%S\"", n->rstring);
		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;
	t->width = ewidth[et];
	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, long b)
{
	Type *t1;

	if(b & BGARB) {
		t1 = copytyp(t);
		t1->garb = simpleg(b);
		return t1;
	}
	return t;
}

int
simpleg(long b)
{

	b &= BGARB;
	switch(b) {
	case BCONSTNT:
		return GCONSTNT;
	case BVOLATILE:
		return GVOLATILE;
	case BVOLATILE|BCONSTNT:
		return GCONSTNT|GVOLATILE;
	}
	return GXXX;
}

int
simplec(long 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(long 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, long ttab[])
{
	int i;
	ulong 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, long 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, long 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, long *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;
}

long
dotoffset(Type *st, Type *lt, Node *n)
{
	Type *t;
	Sym *g;
	long 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;
	long 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;
	long 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(1 && 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)
{
	ulong 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;

/*
	if(debug['h'])
		print("%.3o %ld %ld %d #%.lux\n",
			(s1<<3)|s2, c1, c2, topbit(c3), c3);
*/

	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(ulong 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(long b)
{
	int i;

	for(i=0; i<32; i++)
		if(b & (1L<<i))
			return i;
	diag(Z, "bad in bitno");
	return 0;
}

long
typebitor(long a, long b)
{
	long 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();
}

ulong	thash1	= 0x2edab8c9;
ulong	thash2	= 0x1dc74fb8;
ulong	thash3	= 0x1f241331;
ulong	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",
	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",
	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",
	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[NTYPE];
int	typeiinit[] =
{
	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TVLONG, TUVLONG, -1,
};
uchar	typeu[NTYPE];
int	typeuinit[] =
{
	TUCHAR, TUSHORT, TUINT, TULONG, TUVLONG, TIND, -1,
};

uchar	typesuv[NTYPE];
int	typesuvinit[] =
{
	TVLONG, TUVLONG, TSTRUCT, TUNION, -1,
};

uchar	typeilp[NTYPE];
int	typeilpinit[] =
{
	TINT, TUINT, TLONG, TULONG, TIND, -1
};

uchar	typechl[NTYPE];
uchar	typechlv[NTYPE];
uchar	typechlvp[NTYPE];
int	typechlinit[] =
{
	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1,
};

uchar	typechlp[NTYPE];
int	typechlpinit[] =
{
	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TIND, -1,
};

uchar	typechlpfd[NTYPE];
int	typechlpfdinit[] =
{
	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TIND, -1,
};

uchar	typec[NTYPE];
int	typecinit[] =
{
	TCHAR, TUCHAR, -1
};

uchar	typeh[NTYPE];
int	typehinit[] =
{
	TSHORT, TUSHORT, -1,
};

uchar	typeil[NTYPE];
int	typeilinit[] =
{
	TINT, TUINT, TLONG, TULONG, -1,
};

uchar	typev[NTYPE];
int	typevinit[] =
{
	TVLONG,	TUVLONG, -1,
};

uchar	typefd[NTYPE];
int	typefdinit[] =
{
	TFLOAT, TDOUBLE, -1,
};

uchar	typeaf[NTYPE];
int	typeafinit[] =
{
	TFUNC, TARRAY, -1,
};

uchar	typesu[NTYPE];
int	typesuinit[] =
{
	TSTRUCT, TUNION, -1,
};

long	tasign[NTYPE];
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,
};

long	tasadd[NTYPE];
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,
};

long	tcast[NTYPE];
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,
};

long	tadd[NTYPE];
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,
};

long	tsub[NTYPE];
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,
};

long	tmul[NTYPE];
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,
};

long	tand[NTYPE];
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,
};

long	trel[NTYPE];
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,
};

long	tfunct[1] =
{
	BFUNC,
};

long	tindir[1] =
{
	BIND,
};

long	tdot[1] =
{
	BSTRUCT|BUNION,
};

long	tnot[1] =
{
	BNUMBER|BIND,
};

long	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];
}
