xref: /plan9-contrib/sys/src/cmd/cc/sub.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
13e12c5d1SDavid du Colombier #include	"cc.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier Node*
new(int t,Node * l,Node * r)43e12c5d1SDavid du Colombier new(int t, Node *l, Node *r)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	Node *n;
73e12c5d1SDavid du Colombier 
87dd7cddfSDavid du Colombier 	n = alloc(sizeof(*n));
93e12c5d1SDavid du Colombier 	n->op = t;
103e12c5d1SDavid du Colombier 	n->left = l;
113e12c5d1SDavid du Colombier 	n->right = r;
12b85a8364SDavid du Colombier 	if(l && t != OGOTO)
13b85a8364SDavid du Colombier 		n->lineno = l->lineno;
14b85a8364SDavid du Colombier 	else if(r)
15b85a8364SDavid du Colombier 		n->lineno = r->lineno;
16b85a8364SDavid du Colombier 	else
173e12c5d1SDavid du Colombier 		n->lineno = lineno;
183e12c5d1SDavid du Colombier 	newflag = 1;
193e12c5d1SDavid du Colombier 	return n;
203e12c5d1SDavid du Colombier }
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier Node*
new1(int o,Node * l,Node * r)233e12c5d1SDavid du Colombier new1(int o, Node *l, Node *r)
243e12c5d1SDavid du Colombier {
253e12c5d1SDavid du Colombier 	Node *n;
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	n = new(o, l, r);
283e12c5d1SDavid du Colombier 	n->lineno = nearln;
293e12c5d1SDavid du Colombier 	return n;
303e12c5d1SDavid du Colombier }
313e12c5d1SDavid du Colombier 
323e12c5d1SDavid du Colombier void
prtree(Node * n,char * s)333e12c5d1SDavid du Colombier prtree(Node *n, char *s)
343e12c5d1SDavid du Colombier {
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	print(" == %s ==\n", s);
373e12c5d1SDavid du Colombier 	prtree1(n, 0, 0);
383e12c5d1SDavid du Colombier 	print("\n");
393e12c5d1SDavid du Colombier }
403e12c5d1SDavid du Colombier 
413e12c5d1SDavid du Colombier void
prtree1(Node * n,int d,int f)423e12c5d1SDavid du Colombier prtree1(Node *n, int d, int f)
433e12c5d1SDavid du Colombier {
443e12c5d1SDavid du Colombier 	int i;
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	if(f)
473e12c5d1SDavid du Colombier 	for(i=0; i<d; i++)
483e12c5d1SDavid du Colombier 		print("   ");
493e12c5d1SDavid du Colombier 	if(n == Z) {
503e12c5d1SDavid du Colombier 		print("Z\n");
513e12c5d1SDavid du Colombier 		return;
523e12c5d1SDavid du Colombier 	}
533e12c5d1SDavid du Colombier 	if(n->op == OLIST) {
543e12c5d1SDavid du Colombier 		prtree1(n->left, d, 0);
553e12c5d1SDavid du Colombier 		prtree1(n->right, d, 1);
563e12c5d1SDavid du Colombier 		return;
573e12c5d1SDavid du Colombier 	}
583e12c5d1SDavid du Colombier 	d++;
593e12c5d1SDavid du Colombier 	print("%O", n->op);
603e12c5d1SDavid du Colombier 	i = 3;
613e12c5d1SDavid du Colombier 	switch(n->op)
623e12c5d1SDavid du Colombier 	{
633e12c5d1SDavid du Colombier 	case ONAME:
64219b2ee8SDavid du Colombier 		print(" \"%F\"", n);
65219b2ee8SDavid du Colombier 		print(" %ld", n->xoffset);
663e12c5d1SDavid du Colombier 		i = 0;
673e12c5d1SDavid du Colombier 		break;
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier 	case OINDREG:
70219b2ee8SDavid du Colombier 		print(" %ld(R%d)", n->xoffset, n->reg);
713e12c5d1SDavid du Colombier 		i = 0;
723e12c5d1SDavid du Colombier 		break;
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier 	case OREGISTER:
75219b2ee8SDavid du Colombier 		if(n->xoffset)
76219b2ee8SDavid du Colombier 			print(" %ld+R%d", n->xoffset, n->reg);
773e12c5d1SDavid du Colombier 		else
783e12c5d1SDavid du Colombier 			print(" R%d", n->reg);
793e12c5d1SDavid du Colombier 		i = 0;
803e12c5d1SDavid du Colombier 		break;
813e12c5d1SDavid du Colombier 
823e12c5d1SDavid du Colombier 	case OSTRING:
83219b2ee8SDavid du Colombier 		print(" \"%s\"", n->cstring);
843e12c5d1SDavid du Colombier 		i = 0;
853e12c5d1SDavid du Colombier 		break;
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	case OLSTRING:
8882726826SDavid du Colombier 		if(sizeof(TRune) == sizeof(Rune))
8982726826SDavid du Colombier 			print(" \"%S\"", (Rune*)n->rstring);
9082726826SDavid du Colombier 		else
9182726826SDavid du Colombier 			print(" \"...\"");
923e12c5d1SDavid du Colombier 		i = 0;
933e12c5d1SDavid du Colombier 		break;
943e12c5d1SDavid du Colombier 
953e12c5d1SDavid du Colombier 	case ODOT:
96219b2ee8SDavid du Colombier 	case OELEM:
97219b2ee8SDavid du Colombier 		print(" \"%F\"", n);
983e12c5d1SDavid du Colombier 		break;
993e12c5d1SDavid du Colombier 
1003e12c5d1SDavid du Colombier 	case OCONST:
101219b2ee8SDavid du Colombier 		if(typefd[n->type->etype])
102219b2ee8SDavid du Colombier 			print(" \"%.8e\"", n->fconst);
1033e12c5d1SDavid du Colombier 		else
104219b2ee8SDavid du Colombier 			print(" \"%lld\"", n->vconst);
1053e12c5d1SDavid du Colombier 		i = 0;
1063e12c5d1SDavid du Colombier 		break;
1073e12c5d1SDavid du Colombier 	}
1083e12c5d1SDavid du Colombier 	if(n->addable != 0)
1093e12c5d1SDavid du Colombier 		print(" <%d>", n->addable);
1103e12c5d1SDavid du Colombier 	if(n->type != T)
1113e12c5d1SDavid du Colombier 		print(" %T", n->type);
1123e12c5d1SDavid du Colombier 	if(n->complex != 0)
1133e12c5d1SDavid du Colombier 		print(" (%d)", n->complex);
114b85a8364SDavid du Colombier 	print(" %L\n", n->lineno);
1153e12c5d1SDavid du Colombier 	if(i & 2)
1163e12c5d1SDavid du Colombier 		prtree1(n->left, d, 1);
1173e12c5d1SDavid du Colombier 	if(i & 1)
1183e12c5d1SDavid du Colombier 		prtree1(n->right, d, 1);
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier Type*
typ(int et,Type * d)1223e12c5d1SDavid du Colombier typ(int et, Type *d)
1233e12c5d1SDavid du Colombier {
1243e12c5d1SDavid du Colombier 	Type *t;
1253e12c5d1SDavid du Colombier 
1267dd7cddfSDavid du Colombier 	t = alloc(sizeof(*t));
1273e12c5d1SDavid du Colombier 	t->etype = et;
1283e12c5d1SDavid du Colombier 	t->link = d;
1293e12c5d1SDavid du Colombier 	t->down = T;
1303e12c5d1SDavid du Colombier 	t->sym = S;
1313e12c5d1SDavid du Colombier 	t->width = ewidth[et];
1323e12c5d1SDavid du Colombier 	t->offset = 0;
1333e12c5d1SDavid du Colombier 	t->shift = 0;
1343e12c5d1SDavid du Colombier 	t->nbits = 0;
1357dd7cddfSDavid du Colombier 	t->garb = 0;
1363e12c5d1SDavid du Colombier 	return t;
1373e12c5d1SDavid du Colombier }
1383e12c5d1SDavid du Colombier 
1397dd7cddfSDavid du Colombier Type*
copytyp(Type * t)14080ee5cbfSDavid du Colombier copytyp(Type *t)
14180ee5cbfSDavid du Colombier {
14280ee5cbfSDavid du Colombier 	Type *nt;
14380ee5cbfSDavid du Colombier 
14480ee5cbfSDavid du Colombier 	nt = typ(TXXX, T);
14580ee5cbfSDavid du Colombier 	*nt = *t;
14680ee5cbfSDavid du Colombier 	return nt;
14780ee5cbfSDavid du Colombier }
14880ee5cbfSDavid du Colombier 
14980ee5cbfSDavid du Colombier Type*
garbt(Type * t,long b)1507dd7cddfSDavid du Colombier garbt(Type *t, long b)
1517dd7cddfSDavid du Colombier {
1527dd7cddfSDavid du Colombier 	Type *t1;
1537dd7cddfSDavid du Colombier 
1547dd7cddfSDavid du Colombier 	if(b & BGARB) {
15580ee5cbfSDavid du Colombier 		t1 = copytyp(t);
1567dd7cddfSDavid du Colombier 		t1->garb = simpleg(b);
1577dd7cddfSDavid du Colombier 		return t1;
1587dd7cddfSDavid du Colombier 	}
1597dd7cddfSDavid du Colombier 	return t;
1607dd7cddfSDavid du Colombier }
1617dd7cddfSDavid du Colombier 
1627dd7cddfSDavid du Colombier int
simpleg(long b)1637dd7cddfSDavid du Colombier simpleg(long b)
1647dd7cddfSDavid du Colombier {
1657dd7cddfSDavid du Colombier 
1667dd7cddfSDavid du Colombier 	b &= BGARB;
1677dd7cddfSDavid du Colombier 	switch(b) {
1687dd7cddfSDavid du Colombier 	case BCONSTNT:
1697dd7cddfSDavid du Colombier 		return GCONSTNT;
1707dd7cddfSDavid du Colombier 	case BVOLATILE:
1717dd7cddfSDavid du Colombier 		return GVOLATILE;
1727dd7cddfSDavid du Colombier 	case BVOLATILE|BCONSTNT:
1737dd7cddfSDavid du Colombier 		return GCONSTNT|GVOLATILE;
1747dd7cddfSDavid du Colombier 	}
1757dd7cddfSDavid du Colombier 	return GXXX;
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier 
1783e12c5d1SDavid du Colombier int
simplec(long b)1793e12c5d1SDavid du Colombier simplec(long b)
1803e12c5d1SDavid du Colombier {
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier 	b &= BCLASS;
1833e12c5d1SDavid du Colombier 	switch(b) {
1843e12c5d1SDavid du Colombier 	case 0:
1853e12c5d1SDavid du Colombier 	case BREGISTER:
1863e12c5d1SDavid du Colombier 		return CXXX;
1873e12c5d1SDavid du Colombier 	case BAUTO:
1883e12c5d1SDavid du Colombier 	case BAUTO|BREGISTER:
1893e12c5d1SDavid du Colombier 		return CAUTO;
1903e12c5d1SDavid du Colombier 	case BEXTERN:
1913e12c5d1SDavid du Colombier 		return CEXTERN;
1923e12c5d1SDavid du Colombier 	case BEXTERN|BREGISTER:
1933e12c5d1SDavid du Colombier 		return CEXREG;
1943e12c5d1SDavid du Colombier 	case BSTATIC:
1953e12c5d1SDavid du Colombier 		return CSTATIC;
1963e12c5d1SDavid du Colombier 	case BTYPEDEF:
1973e12c5d1SDavid du Colombier 		return CTYPEDEF;
19880ee5cbfSDavid du Colombier 	case BTYPESTR:
19980ee5cbfSDavid du Colombier 		return CTYPESTR;
2003e12c5d1SDavid du Colombier 	}
2013e12c5d1SDavid du Colombier 	diag(Z, "illegal combination of classes %Q", b);
2023e12c5d1SDavid du Colombier 	return CXXX;
2033e12c5d1SDavid du Colombier }
2043e12c5d1SDavid du Colombier 
2053e12c5d1SDavid du Colombier Type*
simplet(long b)2063e12c5d1SDavid du Colombier simplet(long b)
2073e12c5d1SDavid du Colombier {
2083e12c5d1SDavid du Colombier 
2097dd7cddfSDavid du Colombier 	b &= ~BCLASS & ~BGARB;
2103e12c5d1SDavid du Colombier 	switch(b) {
2113e12c5d1SDavid du Colombier 	case BCHAR:
2123e12c5d1SDavid du Colombier 	case BCHAR|BSIGNED:
2133e12c5d1SDavid du Colombier 		return types[TCHAR];
2143e12c5d1SDavid du Colombier 
2153e12c5d1SDavid du Colombier 	case BCHAR|BUNSIGNED:
2163e12c5d1SDavid du Colombier 		return types[TUCHAR];
2173e12c5d1SDavid du Colombier 
2183e12c5d1SDavid du Colombier 	case BSHORT:
2193e12c5d1SDavid du Colombier 	case BSHORT|BINT:
2203e12c5d1SDavid du Colombier 	case BSHORT|BSIGNED:
2213e12c5d1SDavid du Colombier 	case BSHORT|BINT|BSIGNED:
2223e12c5d1SDavid du Colombier 		return types[TSHORT];
2233e12c5d1SDavid du Colombier 
2243e12c5d1SDavid du Colombier 	case BUNSIGNED|BSHORT:
2253e12c5d1SDavid du Colombier 	case BUNSIGNED|BSHORT|BINT:
2263e12c5d1SDavid du Colombier 		return types[TUSHORT];
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 	case 0:
2293e12c5d1SDavid du Colombier 	case BINT:
2303e12c5d1SDavid du Colombier 	case BINT|BSIGNED:
2313e12c5d1SDavid du Colombier 	case BSIGNED:
2327dd7cddfSDavid du Colombier 		return types[TINT];
2333e12c5d1SDavid du Colombier 
2343e12c5d1SDavid du Colombier 	case BUNSIGNED:
2353e12c5d1SDavid du Colombier 	case BUNSIGNED|BINT:
2367dd7cddfSDavid du Colombier 		return types[TUINT];
2373e12c5d1SDavid du Colombier 
2383e12c5d1SDavid du Colombier 	case BLONG:
2393e12c5d1SDavid du Colombier 	case BLONG|BINT:
2403e12c5d1SDavid du Colombier 	case BLONG|BSIGNED:
2413e12c5d1SDavid du Colombier 	case BLONG|BINT|BSIGNED:
2423e12c5d1SDavid du Colombier 		return types[TLONG];
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier 	case BUNSIGNED|BLONG:
2453e12c5d1SDavid du Colombier 	case BUNSIGNED|BLONG|BINT:
2463e12c5d1SDavid du Colombier 		return types[TULONG];
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier 	case BVLONG|BLONG:
2493e12c5d1SDavid du Colombier 	case BVLONG|BLONG|BINT:
2503e12c5d1SDavid du Colombier 	case BVLONG|BLONG|BSIGNED:
2513e12c5d1SDavid du Colombier 	case BVLONG|BLONG|BINT|BSIGNED:
2523e12c5d1SDavid du Colombier 		return types[TVLONG];
2533e12c5d1SDavid du Colombier 
254219b2ee8SDavid du Colombier 	case BVLONG|BLONG|BUNSIGNED:
255219b2ee8SDavid du Colombier 	case BVLONG|BLONG|BINT|BUNSIGNED:
256219b2ee8SDavid du Colombier 		return types[TUVLONG];
257219b2ee8SDavid du Colombier 
2583e12c5d1SDavid du Colombier 	case BFLOAT:
2593e12c5d1SDavid du Colombier 		return types[TFLOAT];
2603e12c5d1SDavid du Colombier 
2613e12c5d1SDavid du Colombier 	case BDOUBLE:
2623e12c5d1SDavid du Colombier 	case BDOUBLE|BLONG:
2633e12c5d1SDavid du Colombier 	case BFLOAT|BLONG:
2643e12c5d1SDavid du Colombier 		return types[TDOUBLE];
2653e12c5d1SDavid du Colombier 
2663e12c5d1SDavid du Colombier 	case BVOID:
2673e12c5d1SDavid du Colombier 		return types[TVOID];
2683e12c5d1SDavid du Colombier 	}
2693e12c5d1SDavid du Colombier 
2703e12c5d1SDavid du Colombier 	diag(Z, "illegal combination of types %Q", b);
2717dd7cddfSDavid du Colombier 	return types[TINT];
2723e12c5d1SDavid du Colombier }
2733e12c5d1SDavid du Colombier 
2743e12c5d1SDavid du Colombier int
stcompat(Node * n,Type * t1,Type * t2,long ttab[])2753e12c5d1SDavid du Colombier stcompat(Node *n, Type *t1, Type *t2, long ttab[])
2763e12c5d1SDavid du Colombier {
2777dd7cddfSDavid du Colombier 	int i;
2787dd7cddfSDavid du Colombier 	ulong b;
2793e12c5d1SDavid du Colombier 
2803e12c5d1SDavid du Colombier 	i = 0;
2813e12c5d1SDavid du Colombier 	if(t2 != T)
2823e12c5d1SDavid du Colombier 		i = t2->etype;
2833e12c5d1SDavid du Colombier 	b = 1L << i;
2843e12c5d1SDavid du Colombier 	i = 0;
2853e12c5d1SDavid du Colombier 	if(t1 != T)
2863e12c5d1SDavid du Colombier 		i = t1->etype;
2873e12c5d1SDavid du Colombier 	if(b & ttab[i]) {
2883e12c5d1SDavid du Colombier 		if(ttab == tasign)
2893e12c5d1SDavid du Colombier 			if(b == BSTRUCT || b == BUNION)
2903e12c5d1SDavid du Colombier 				if(!sametype(t1, t2))
2913e12c5d1SDavid du Colombier 					return 1;
2923e12c5d1SDavid du Colombier 		if(n->op != OCAST)
2933e12c5d1SDavid du Colombier 		 	if(b == BIND && i == TIND)
2943e12c5d1SDavid du Colombier 				if(!sametype(t1, t2))
2953e12c5d1SDavid du Colombier 					return 1;
2963e12c5d1SDavid du Colombier 		return 0;
2973e12c5d1SDavid du Colombier 	}
2983e12c5d1SDavid du Colombier 	return 1;
2993e12c5d1SDavid du Colombier }
3003e12c5d1SDavid du Colombier 
3013e12c5d1SDavid du Colombier int
tcompat(Node * n,Type * t1,Type * t2,long ttab[])3023e12c5d1SDavid du Colombier tcompat(Node *n, Type *t1, Type *t2, long ttab[])
3033e12c5d1SDavid du Colombier {
3043e12c5d1SDavid du Colombier 
3053e12c5d1SDavid du Colombier 	if(stcompat(n, t1, t2, ttab)) {
3063e12c5d1SDavid du Colombier 		if(t1 == T)
3073e12c5d1SDavid du Colombier 			diag(n, "incompatible type: \"%T\" for op \"%O\"",
3083e12c5d1SDavid du Colombier 				t2, n->op);
3093e12c5d1SDavid du Colombier 		else
3103e12c5d1SDavid du Colombier 			diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"",
3113e12c5d1SDavid du Colombier 				t1, t2, n->op);
3123e12c5d1SDavid du Colombier 		return 1;
3133e12c5d1SDavid du Colombier 	}
3143e12c5d1SDavid du Colombier 	return 0;
3153e12c5d1SDavid du Colombier }
3163e12c5d1SDavid du Colombier 
3173e12c5d1SDavid du Colombier void
makedot(Node * n,Type * t,long o)3183e12c5d1SDavid du Colombier makedot(Node *n, Type *t, long o)
3193e12c5d1SDavid du Colombier {
3203e12c5d1SDavid du Colombier 	Node *n1, *n2;
3213e12c5d1SDavid du Colombier 
3223e12c5d1SDavid du Colombier 	if(t->nbits) {
3233e12c5d1SDavid du Colombier 		n1 = new(OXXX, Z, Z);
3243e12c5d1SDavid du Colombier 		*n1 = *n;
3253e12c5d1SDavid du Colombier 		n->op = OBIT;
3263e12c5d1SDavid du Colombier 		n->left = n1;
3273e12c5d1SDavid du Colombier 		n->right = Z;
3283e12c5d1SDavid du Colombier 		n->type = t;
3293e12c5d1SDavid du Colombier 		n->addable = n1->left->addable;
3303e12c5d1SDavid du Colombier 		n = n1;
3313e12c5d1SDavid du Colombier 	}
3323e12c5d1SDavid du Colombier 	n->addable = n->left->addable;
3333e12c5d1SDavid du Colombier 	if(n->addable == 0) {
3343e12c5d1SDavid du Colombier 		n1 = new1(OCONST, Z, Z);
335219b2ee8SDavid du Colombier 		n1->vconst = o;
3363e12c5d1SDavid du Colombier 		n1->type = types[TLONG];
3373e12c5d1SDavid du Colombier 		n->right = n1;
3383e12c5d1SDavid du Colombier 		n->type = t;
3393e12c5d1SDavid du Colombier 		return;
3403e12c5d1SDavid du Colombier 	}
3413e12c5d1SDavid du Colombier 	n->left->type = t;
3423e12c5d1SDavid du Colombier 	if(o == 0) {
3433e12c5d1SDavid du Colombier 		*n = *n->left;
3443e12c5d1SDavid du Colombier 		return;
3453e12c5d1SDavid du Colombier 	}
3463e12c5d1SDavid du Colombier 	n->type = t;
3473e12c5d1SDavid du Colombier 	n1 = new1(OCONST, Z, Z);
348219b2ee8SDavid du Colombier 	n1->vconst = o;
3493e12c5d1SDavid du Colombier 	t = typ(TIND, t);
3503e12c5d1SDavid du Colombier 	t->width = types[TIND]->width;
3513e12c5d1SDavid du Colombier 	n1->type = t;
3523e12c5d1SDavid du Colombier 
3533e12c5d1SDavid du Colombier 	n2 = new1(OADDR, n->left, Z);
3543e12c5d1SDavid du Colombier 	n2->type = t;
3553e12c5d1SDavid du Colombier 
3563e12c5d1SDavid du Colombier 	n1 = new1(OADD, n1, n2);
3573e12c5d1SDavid du Colombier 	n1->type = t;
3583e12c5d1SDavid du Colombier 
3593e12c5d1SDavid du Colombier 	n->op = OIND;
3603e12c5d1SDavid du Colombier 	n->left = n1;
3613e12c5d1SDavid du Colombier 	n->right = Z;
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier 
3643e12c5d1SDavid du Colombier Type*
dotsearch(Sym * s,Type * t,Node * n,long * off)36580ee5cbfSDavid du Colombier dotsearch(Sym *s, Type *t, Node *n, long *off)
3663e12c5d1SDavid du Colombier {
36780ee5cbfSDavid du Colombier 	Type *t1, *xt, *rt;
3683e12c5d1SDavid du Colombier 
3693e12c5d1SDavid du Colombier 	xt = T;
3703e12c5d1SDavid du Colombier 
3713e12c5d1SDavid du Colombier 	/*
3723e12c5d1SDavid du Colombier 	 * look it up by name
3733e12c5d1SDavid du Colombier 	 */
3743e12c5d1SDavid du Colombier 	for(t1 = t; t1 != T; t1 = t1->down)
3753e12c5d1SDavid du Colombier 		if(t1->sym == s) {
3763e12c5d1SDavid du Colombier 			if(xt != T)
3773e12c5d1SDavid du Colombier 				goto ambig;
3783e12c5d1SDavid du Colombier 			xt = t1;
3793e12c5d1SDavid du Colombier 		}
3803e12c5d1SDavid du Colombier 
3813e12c5d1SDavid du Colombier 	/*
3823e12c5d1SDavid du Colombier 	 * look it up by type
3833e12c5d1SDavid du Colombier 	 */
38480ee5cbfSDavid du Colombier 	if(s->class == CTYPEDEF || s->class == CTYPESTR)
3853e12c5d1SDavid du Colombier 		for(t1 = t; t1 != T; t1 = t1->down)
3863e12c5d1SDavid du Colombier 			if(t1->sym == S && typesu[t1->etype])
3873e12c5d1SDavid du Colombier 				if(sametype(s->type, t1)) {
3883e12c5d1SDavid du Colombier 					if(xt != T)
3893e12c5d1SDavid du Colombier 						goto ambig;
3903e12c5d1SDavid du Colombier 					xt = t1;
3913e12c5d1SDavid du Colombier 				}
39280ee5cbfSDavid du Colombier 	if(xt != T) {
39380ee5cbfSDavid du Colombier 		*off = xt->offset;
3943e12c5d1SDavid du Colombier 		return xt;
39580ee5cbfSDavid du Colombier 	}
3963e12c5d1SDavid du Colombier 
3973e12c5d1SDavid du Colombier 	/*
3983e12c5d1SDavid du Colombier 	 * look it up in unnamed substructures
3993e12c5d1SDavid du Colombier 	 */
4003e12c5d1SDavid du Colombier 	for(t1 = t; t1 != T; t1 = t1->down)
40180ee5cbfSDavid du Colombier 		if(t1->sym == S && typesu[t1->etype]){
40280ee5cbfSDavid du Colombier 			rt = dotsearch(s, t1->link, n, off);
40380ee5cbfSDavid du Colombier 			if(rt != T) {
4043e12c5d1SDavid du Colombier 				if(xt != T)
4053e12c5d1SDavid du Colombier 					goto ambig;
40680ee5cbfSDavid du Colombier 				xt = rt;
40780ee5cbfSDavid du Colombier 				*off += t1->offset;
40880ee5cbfSDavid du Colombier 			}
4093e12c5d1SDavid du Colombier 		}
4103e12c5d1SDavid du Colombier 	return xt;
4113e12c5d1SDavid du Colombier 
4123e12c5d1SDavid du Colombier ambig:
4133e12c5d1SDavid du Colombier 	diag(n, "ambiguous structure element: %s", s->name);
4143e12c5d1SDavid du Colombier 	return xt;
4153e12c5d1SDavid du Colombier }
4163e12c5d1SDavid du Colombier 
4173e12c5d1SDavid du Colombier long
dotoffset(Type * st,Type * lt,Node * n)4183e12c5d1SDavid du Colombier dotoffset(Type *st, Type *lt, Node *n)
4193e12c5d1SDavid du Colombier {
4203e12c5d1SDavid du Colombier 	Type *t;
4213e12c5d1SDavid du Colombier 	Sym *g;
4223e12c5d1SDavid du Colombier 	long o, o1;
4233e12c5d1SDavid du Colombier 
4243e12c5d1SDavid du Colombier 	o = -1;
4253e12c5d1SDavid du Colombier 	/*
4263e12c5d1SDavid du Colombier 	 * first try matching at the top level
4273e12c5d1SDavid du Colombier 	 * for matching tag names
4283e12c5d1SDavid du Colombier 	 */
4293e12c5d1SDavid du Colombier 	g = st->tag;
4303e12c5d1SDavid du Colombier 	if(g != S)
4313e12c5d1SDavid du Colombier 		for(t=lt->link; t!=T; t=t->down)
4323e12c5d1SDavid du Colombier 			if(t->sym == S)
4333e12c5d1SDavid du Colombier 				if(g == t->tag) {
4343e12c5d1SDavid du Colombier 					if(o >= 0)
4353e12c5d1SDavid du Colombier 						goto ambig;
4363e12c5d1SDavid du Colombier 					o = t->offset;
4373e12c5d1SDavid du Colombier 				}
4383e12c5d1SDavid du Colombier 	if(o >= 0)
4393e12c5d1SDavid du Colombier 		return o;
4403e12c5d1SDavid du Colombier 
4413e12c5d1SDavid du Colombier 	/*
4423e12c5d1SDavid du Colombier 	 * second try matching at the top level
4433e12c5d1SDavid du Colombier 	 * for similar types
4443e12c5d1SDavid du Colombier 	 */
4453e12c5d1SDavid du Colombier 	for(t=lt->link; t!=T; t=t->down)
4463e12c5d1SDavid du Colombier 		if(t->sym == S)
4473e12c5d1SDavid du Colombier 			if(sametype(st, t)) {
4483e12c5d1SDavid du Colombier 				if(o >= 0)
4493e12c5d1SDavid du Colombier 					goto ambig;
4503e12c5d1SDavid du Colombier 				o = t->offset;
4513e12c5d1SDavid du Colombier 			}
4523e12c5d1SDavid du Colombier 	if(o >= 0)
4533e12c5d1SDavid du Colombier 		return o;
4543e12c5d1SDavid du Colombier 
4553e12c5d1SDavid du Colombier 	/*
4563e12c5d1SDavid du Colombier 	 * last try matching sub-levels
4573e12c5d1SDavid du Colombier 	 */
4583e12c5d1SDavid du Colombier 	for(t=lt->link; t!=T; t=t->down)
4593e12c5d1SDavid du Colombier 		if(t->sym == S)
4603e12c5d1SDavid du Colombier 		if(typesu[t->etype]) {
4613e12c5d1SDavid du Colombier 			o1 = dotoffset(st, t, n);
4623e12c5d1SDavid du Colombier 			if(o1 >= 0) {
4633e12c5d1SDavid du Colombier 				if(o >= 0)
4643e12c5d1SDavid du Colombier 					goto ambig;
4653e12c5d1SDavid du Colombier 				o = o1 + t->offset;
4663e12c5d1SDavid du Colombier 			}
4673e12c5d1SDavid du Colombier 		}
4683e12c5d1SDavid du Colombier 	return o;
4693e12c5d1SDavid du Colombier 
4703e12c5d1SDavid du Colombier ambig:
4713e12c5d1SDavid du Colombier 	diag(n, "ambiguous unnamed structure element");
4723e12c5d1SDavid du Colombier 	return o;
4733e12c5d1SDavid du Colombier }
4743e12c5d1SDavid du Colombier 
475219b2ee8SDavid du Colombier /*
476219b2ee8SDavid du Colombier  * look into tree for floating point constant expressions
477219b2ee8SDavid du Colombier  */
478219b2ee8SDavid du Colombier int
allfloat(Node * n,int flag)479219b2ee8SDavid du Colombier allfloat(Node *n, int flag)
480219b2ee8SDavid du Colombier {
481219b2ee8SDavid du Colombier 
482219b2ee8SDavid du Colombier 	if(n != Z) {
483219b2ee8SDavid du Colombier 		if(n->type->etype != TDOUBLE)
484219b2ee8SDavid du Colombier 			return 1;
485219b2ee8SDavid du Colombier 		switch(n->op) {
486219b2ee8SDavid du Colombier 		case OCONST:
487219b2ee8SDavid du Colombier 			if(flag)
488219b2ee8SDavid du Colombier 				n->type = types[TFLOAT];
489219b2ee8SDavid du Colombier 			return 1;
490219b2ee8SDavid du Colombier 		case OADD:	/* no need to get more exotic than this */
491219b2ee8SDavid du Colombier 		case OSUB:
492219b2ee8SDavid du Colombier 		case OMUL:
493219b2ee8SDavid du Colombier 		case ODIV:
494219b2ee8SDavid du Colombier 			if(!allfloat(n->right, flag))
495219b2ee8SDavid du Colombier 				break;
496219b2ee8SDavid du Colombier 		case OCAST:
497219b2ee8SDavid du Colombier 			if(!allfloat(n->left, flag))
498219b2ee8SDavid du Colombier 				break;
499219b2ee8SDavid du Colombier 			if(flag)
500219b2ee8SDavid du Colombier 				n->type = types[TFLOAT];
501219b2ee8SDavid du Colombier 			return 1;
502219b2ee8SDavid du Colombier 		}
503219b2ee8SDavid du Colombier 	}
504219b2ee8SDavid du Colombier 	return 0;
505219b2ee8SDavid du Colombier }
506219b2ee8SDavid du Colombier 
507219b2ee8SDavid du Colombier void
constas(Node * n,Type * il,Type * ir)5087dd7cddfSDavid du Colombier constas(Node *n, Type *il, Type *ir)
5097dd7cddfSDavid du Colombier {
5107dd7cddfSDavid du Colombier 	Type *l, *r;
5117dd7cddfSDavid du Colombier 
5127dd7cddfSDavid du Colombier 	l = il;
5137dd7cddfSDavid du Colombier 	r = ir;
5147dd7cddfSDavid du Colombier 
5157dd7cddfSDavid du Colombier 	if(l == T)
5167dd7cddfSDavid du Colombier 		return;
5177dd7cddfSDavid du Colombier 	if(l->garb & GCONSTNT) {
5187dd7cddfSDavid du Colombier 		warn(n, "assignment to a constant type (%T)", il);
5197dd7cddfSDavid du Colombier 		return;
5207dd7cddfSDavid du Colombier 	}
5217dd7cddfSDavid du Colombier 	if(r == T)
5227dd7cddfSDavid du Colombier 		return;
5237dd7cddfSDavid du Colombier 	for(;;) {
5247dd7cddfSDavid du Colombier 		if(l->etype != TIND || r->etype != TIND)
5257dd7cddfSDavid du Colombier 			break;
5267dd7cddfSDavid du Colombier 		l = l->link;
5277dd7cddfSDavid du Colombier 		r = r->link;
5287dd7cddfSDavid du Colombier 		if(l == T || r == T)
5297dd7cddfSDavid du Colombier 			break;
5307dd7cddfSDavid du Colombier 		if(r->garb & GCONSTNT)
5317dd7cddfSDavid du Colombier 			if(!(l->garb & GCONSTNT)) {
5327dd7cddfSDavid du Colombier 				warn(n, "assignment of a constant pointer type (%T)", ir);
5337dd7cddfSDavid du Colombier 				break;
5347dd7cddfSDavid du Colombier 			}
5357dd7cddfSDavid du Colombier 	}
5367dd7cddfSDavid du Colombier }
5377dd7cddfSDavid du Colombier 
5387dd7cddfSDavid du Colombier void
typeext1(Type * st,Node * l)539219b2ee8SDavid du Colombier typeext1(Type *st, Node *l)
540219b2ee8SDavid du Colombier {
541219b2ee8SDavid du Colombier 	if(st->etype == TFLOAT && allfloat(l, 0))
542219b2ee8SDavid du Colombier 		allfloat(l, 1);
543219b2ee8SDavid du Colombier }
544219b2ee8SDavid du Colombier 
5453e12c5d1SDavid du Colombier void
typeext(Type * st,Node * l)5463e12c5d1SDavid du Colombier typeext(Type *st, Node *l)
5473e12c5d1SDavid du Colombier {
5483e12c5d1SDavid du Colombier 	Type *lt;
5493e12c5d1SDavid du Colombier 	Node *n1, *n2;
5503e12c5d1SDavid du Colombier 	long o;
5513e12c5d1SDavid du Colombier 
5523e12c5d1SDavid du Colombier 	lt = l->type;
5533e12c5d1SDavid du Colombier 	if(lt == T)
5543e12c5d1SDavid du Colombier 		return;
5553e12c5d1SDavid du Colombier 	if(st->etype == TIND && vconst(l) == 0) {
5563e12c5d1SDavid du Colombier 		l->type = st;
557219b2ee8SDavid du Colombier 		l->vconst = 0;
5583e12c5d1SDavid du Colombier 		return;
5593e12c5d1SDavid du Colombier 	}
560219b2ee8SDavid du Colombier 	typeext1(st, l);
5613e12c5d1SDavid du Colombier 
5623e12c5d1SDavid du Colombier 	/*
5633e12c5d1SDavid du Colombier 	 * extension of C
5643e12c5d1SDavid du Colombier 	 * if assign of struct containing unnamed sub-struct
5653e12c5d1SDavid du Colombier 	 * to type of sub-struct, insert the DOT.
5663e12c5d1SDavid du Colombier 	 * if assign of *struct containing unnamed substruct
5673e12c5d1SDavid du Colombier 	 * to type of *sub-struct, insert the add-offset
5683e12c5d1SDavid du Colombier 	 */
5693e12c5d1SDavid du Colombier 	if(typesu[st->etype] && typesu[lt->etype]) {
5703e12c5d1SDavid du Colombier 		o = dotoffset(st, lt, l);
5713e12c5d1SDavid du Colombier 		if(o >= 0) {
5723e12c5d1SDavid du Colombier 			n1 = new1(OXXX, Z, Z);
5733e12c5d1SDavid du Colombier 			*n1 = *l;
5743e12c5d1SDavid du Colombier 			l->op = ODOT;
5753e12c5d1SDavid du Colombier 			l->left = n1;
5763e12c5d1SDavid du Colombier 			l->right = Z;
5773e12c5d1SDavid du Colombier 			makedot(l, st, o);
5783e12c5d1SDavid du Colombier 		}
5793e12c5d1SDavid du Colombier 		return;
5803e12c5d1SDavid du Colombier 	}
5813e12c5d1SDavid du Colombier 	if(st->etype == TIND && typesu[st->link->etype])
5823e12c5d1SDavid du Colombier 	if(lt->etype == TIND && typesu[lt->link->etype]) {
5833e12c5d1SDavid du Colombier 		o = dotoffset(st->link, lt->link, l);
5843e12c5d1SDavid du Colombier 		if(o >= 0) {
5853e12c5d1SDavid du Colombier 			l->type = st;
5863e12c5d1SDavid du Colombier 			if(o == 0)
5873e12c5d1SDavid du Colombier 				return;
5883e12c5d1SDavid du Colombier 			n1 = new1(OXXX, Z, Z);
5893e12c5d1SDavid du Colombier 			*n1 = *l;
5903e12c5d1SDavid du Colombier 			n2 = new1(OCONST, Z, Z);
591219b2ee8SDavid du Colombier 			n2->vconst = o;
5923e12c5d1SDavid du Colombier 			n2->type = st;
5933e12c5d1SDavid du Colombier 			l->op = OADD;
5943e12c5d1SDavid du Colombier 			l->left = n1;
5953e12c5d1SDavid du Colombier 			l->right = n2;
5963e12c5d1SDavid du Colombier 		}
5973e12c5d1SDavid du Colombier 		return;
5983e12c5d1SDavid du Colombier 	}
5993e12c5d1SDavid du Colombier }
6003e12c5d1SDavid du Colombier 
6013e12c5d1SDavid du Colombier /*
6023e12c5d1SDavid du Colombier  * a cast that generates no code
6033e12c5d1SDavid du Colombier  * (same size move)
6043e12c5d1SDavid du Colombier  */
6053e12c5d1SDavid du Colombier int
nocast(Type * t1,Type * t2)6063e12c5d1SDavid du Colombier nocast(Type *t1, Type *t2)
6073e12c5d1SDavid du Colombier {
6083e12c5d1SDavid du Colombier 	int i, b;
6093e12c5d1SDavid du Colombier 
6103e12c5d1SDavid du Colombier 	if(t1->nbits)
6113e12c5d1SDavid du Colombier 		return 0;
6123e12c5d1SDavid du Colombier 	i = 0;
6133e12c5d1SDavid du Colombier 	if(t2 != T)
6143e12c5d1SDavid du Colombier 		i = t2->etype;
6153e12c5d1SDavid du Colombier 	b = 1<<i;
6163e12c5d1SDavid du Colombier 	i = 0;
6173e12c5d1SDavid du Colombier 	if(t1 != T)
6183e12c5d1SDavid du Colombier 		i = t1->etype;
6193e12c5d1SDavid du Colombier 	if(b & ncast[i])
6203e12c5d1SDavid du Colombier 		return 1;
6213e12c5d1SDavid du Colombier 	return 0;
6223e12c5d1SDavid du Colombier }
6233e12c5d1SDavid du Colombier 
6243e12c5d1SDavid du Colombier /*
6253e12c5d1SDavid du Colombier  * a cast that has a noop semantic
6263e12c5d1SDavid du Colombier  * (small to large, convert)
6273e12c5d1SDavid du Colombier  */
6283e12c5d1SDavid du Colombier int
nilcast(Type * t1,Type * t2)6293e12c5d1SDavid du Colombier nilcast(Type *t1, Type *t2)
6303e12c5d1SDavid du Colombier {
6317dd7cddfSDavid du Colombier 	int et1, et2;
6323e12c5d1SDavid du Colombier 
6337dd7cddfSDavid du Colombier 	if(t1 == T)
6347dd7cddfSDavid du Colombier 		return 0;
6353e12c5d1SDavid du Colombier 	if(t1->nbits)
6363e12c5d1SDavid du Colombier 		return 0;
6377dd7cddfSDavid du Colombier 	if(t2 == T)
6387dd7cddfSDavid du Colombier 		return 0;
6397dd7cddfSDavid du Colombier 	et1 = t1->etype;
6407dd7cddfSDavid du Colombier 	et2 = t2->etype;
6417dd7cddfSDavid du Colombier 	if(et1 == et2)
6423e12c5d1SDavid du Colombier 		return 1;
6437dd7cddfSDavid du Colombier 	if(typefd[et1] && typefd[et2]) {
6447dd7cddfSDavid du Colombier 		if(ewidth[et1] < ewidth[et2])
6457dd7cddfSDavid du Colombier 			return 1;
6467dd7cddfSDavid du Colombier 		return 0;
6477dd7cddfSDavid du Colombier 	}
6487dd7cddfSDavid du Colombier 	if(typechlp[et1] && typechlp[et2]) {
6497dd7cddfSDavid du Colombier 		if(ewidth[et1] < ewidth[et2])
6507dd7cddfSDavid du Colombier 			return 1;
6517dd7cddfSDavid du Colombier 		return 0;
6527dd7cddfSDavid du Colombier 	}
6533e12c5d1SDavid du Colombier 	return 0;
6543e12c5d1SDavid du Colombier }
6553e12c5d1SDavid du Colombier 
6563e12c5d1SDavid du Colombier /*
6573e12c5d1SDavid du Colombier  * "the usual arithmetic conversions are performed"
6583e12c5d1SDavid du Colombier  */
6593e12c5d1SDavid du Colombier void
arith(Node * n,int f)6603e12c5d1SDavid du Colombier arith(Node *n, int f)
6613e12c5d1SDavid du Colombier {
6623e12c5d1SDavid du Colombier 	Type *t1, *t2;
6633e12c5d1SDavid du Colombier 	int i, j, k;
6643e12c5d1SDavid du Colombier 	Node *n1;
665*40d01547SDavid du Colombier 	long w, x;
6663e12c5d1SDavid du Colombier 
6673e12c5d1SDavid du Colombier 	t1 = n->left->type;
6683e12c5d1SDavid du Colombier 	if(n->right == Z)
6693e12c5d1SDavid du Colombier 		t2 = t1;
6703e12c5d1SDavid du Colombier 	else
6713e12c5d1SDavid du Colombier 		t2 = n->right->type;
6723e12c5d1SDavid du Colombier 	i = TXXX;
6733e12c5d1SDavid du Colombier 	if(t1 != T)
6743e12c5d1SDavid du Colombier 		i = t1->etype;
6753e12c5d1SDavid du Colombier 	j = TXXX;
6763e12c5d1SDavid du Colombier 	if(t2 != T)
6773e12c5d1SDavid du Colombier 		j = t2->etype;
6783e12c5d1SDavid du Colombier 	k = tab[i][j];
6793e12c5d1SDavid du Colombier 	if(k == TIND) {
6803e12c5d1SDavid du Colombier 		if(i == TIND)
6813e12c5d1SDavid du Colombier 			n->type = t1;
6823e12c5d1SDavid du Colombier 		else
6833e12c5d1SDavid du Colombier 		if(j == TIND)
6843e12c5d1SDavid du Colombier 			n->type = t2;
6853e12c5d1SDavid du Colombier 	} else {
6863e12c5d1SDavid du Colombier 		/* convert up to at least int */
6873e12c5d1SDavid du Colombier 		if(f == 1)
6887dd7cddfSDavid du Colombier 		while(k < TINT)
6893e12c5d1SDavid du Colombier 			k += 2;
6903e12c5d1SDavid du Colombier 		n->type = types[k];
6913e12c5d1SDavid du Colombier 	}
6923e12c5d1SDavid du Colombier 	if(n->op == OSUB)
6933e12c5d1SDavid du Colombier 	if(i == TIND && j == TIND) {
6943e12c5d1SDavid du Colombier 		w = n->right->type->link->width;
695*40d01547SDavid du Colombier 		if(w < 1) {
696*40d01547SDavid du Colombier 			snap(n->right->type->link);
697*40d01547SDavid du Colombier 			w = n->right->type->link->width;
698*40d01547SDavid du Colombier 		}
699*40d01547SDavid du Colombier 		x = 0;
700*40d01547SDavid du Colombier 		if(n->left->type->link != T) {
701*40d01547SDavid du Colombier 			x = n->left->type->link->width;
702*40d01547SDavid du Colombier 			if(x < 1) {
703*40d01547SDavid du Colombier 				snap(n->left->type->link);
704*40d01547SDavid du Colombier 				x = n->left->type->link->width;
705*40d01547SDavid du Colombier 			}
706*40d01547SDavid du Colombier 		}
707*40d01547SDavid du Colombier 		if(w < 1 || x < 1)
7083e12c5d1SDavid du Colombier 			goto bad;
7097bd483b0SDavid du Colombier 		n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG];
7107bd483b0SDavid du Colombier 		if(1 && ewidth[TIND] > ewidth[TLONG]){
7117bd483b0SDavid du Colombier 			n1 = new1(OXXX, Z, Z);
7127bd483b0SDavid du Colombier 			*n1 = *n;
7137bd483b0SDavid du Colombier 			n->op = OCAST;
7147bd483b0SDavid du Colombier 			n->left = n1;
7157bd483b0SDavid du Colombier 			n->right = Z;
7167bd483b0SDavid du Colombier 			n->type = types[TLONG];
7177bd483b0SDavid du Colombier 		}
7183e12c5d1SDavid du Colombier 		if(w > 1) {
7193e12c5d1SDavid du Colombier 			n1 = new1(OXXX, Z, Z);
7203e12c5d1SDavid du Colombier 			*n1 = *n;
7213e12c5d1SDavid du Colombier 			n->op = ODIV;
7223e12c5d1SDavid du Colombier 			n->left = n1;
7233e12c5d1SDavid du Colombier 			n1 = new1(OCONST, Z, Z);
72480ee5cbfSDavid du Colombier 			n1->vconst = w;
7253e12c5d1SDavid du Colombier 			n1->type = n->type;
7263e12c5d1SDavid du Colombier 			n->right = n1;
72780ee5cbfSDavid du Colombier 			w = vlog(n1);
72880ee5cbfSDavid du Colombier 			if(w >= 0) {
72980ee5cbfSDavid du Colombier 				n->op = OASHR;
73080ee5cbfSDavid du Colombier 				n1->vconst = w;
73180ee5cbfSDavid du Colombier 			}
7323e12c5d1SDavid du Colombier 		}
7333e12c5d1SDavid du Colombier 		return;
7343e12c5d1SDavid du Colombier 	}
7353e12c5d1SDavid du Colombier 	if(!sametype(n->type, n->left->type)) {
7363e12c5d1SDavid du Colombier 		n->left = new1(OCAST, n->left, Z);
7373e12c5d1SDavid du Colombier 		n->left->type = n->type;
7383e12c5d1SDavid du Colombier 		if(n->type->etype == TIND) {
7393e12c5d1SDavid du Colombier 			w = n->type->link->width;
7407dd7cddfSDavid du Colombier 			if(w < 1) {
7417dd7cddfSDavid du Colombier 				snap(n->type->link);
7427dd7cddfSDavid du Colombier 				w = n->type->link->width;
7433e12c5d1SDavid du Colombier 				if(w < 1)
7443e12c5d1SDavid du Colombier 					goto bad;
7457dd7cddfSDavid du Colombier 			}
7463e12c5d1SDavid du Colombier 			if(w > 1) {
7473e12c5d1SDavid du Colombier 				n1 = new1(OCONST, Z, Z);
748219b2ee8SDavid du Colombier 				n1->vconst = w;
7493e12c5d1SDavid du Colombier 				n1->type = n->type;
7503e12c5d1SDavid du Colombier 				n->left = new1(OMUL, n->left, n1);
7513e12c5d1SDavid du Colombier 				n->left->type = n->type;
7523e12c5d1SDavid du Colombier 			}
7533e12c5d1SDavid du Colombier 		}
7543e12c5d1SDavid du Colombier 	}
7553e12c5d1SDavid du Colombier 	if(n->right != Z)
7563e12c5d1SDavid du Colombier 	if(!sametype(n->type, n->right->type)) {
7573e12c5d1SDavid du Colombier 		n->right = new1(OCAST, n->right, Z);
7583e12c5d1SDavid du Colombier 		n->right->type = n->type;
7593e12c5d1SDavid du Colombier 		if(n->type->etype == TIND) {
7603e12c5d1SDavid du Colombier 			w = n->type->link->width;
7617dd7cddfSDavid du Colombier 			if(w < 1) {
7627dd7cddfSDavid du Colombier 				snap(n->type->link);
7637dd7cddfSDavid du Colombier 				w = n->type->link->width;
7643e12c5d1SDavid du Colombier 				if(w < 1)
7653e12c5d1SDavid du Colombier 					goto bad;
7667dd7cddfSDavid du Colombier 			}
7673e12c5d1SDavid du Colombier 			if(w != 1) {
7683e12c5d1SDavid du Colombier 				n1 = new1(OCONST, Z, Z);
769219b2ee8SDavid du Colombier 				n1->vconst = w;
7703e12c5d1SDavid du Colombier 				n1->type = n->type;
7713e12c5d1SDavid du Colombier 				n->right = new1(OMUL, n->right, n1);
7723e12c5d1SDavid du Colombier 				n->right->type = n->type;
7733e12c5d1SDavid du Colombier 			}
7743e12c5d1SDavid du Colombier 		}
7753e12c5d1SDavid du Colombier 	}
7763e12c5d1SDavid du Colombier 	return;
7773e12c5d1SDavid du Colombier bad:
7787dd7cddfSDavid du Colombier 	diag(n, "pointer addition not fully declared: %T", n->type->link);
7793e12c5d1SDavid du Colombier }
7803e12c5d1SDavid du Colombier 
781375daca8SDavid du Colombier /*
782375daca8SDavid du Colombier  * try to rewrite shift & mask
783375daca8SDavid du Colombier  */
784375daca8SDavid du Colombier void
simplifyshift(Node * n)785375daca8SDavid du Colombier simplifyshift(Node *n)
786375daca8SDavid du Colombier {
787375daca8SDavid du Colombier 	ulong c3;
788375daca8SDavid du Colombier 	int o, s1, s2, c1, c2;
789375daca8SDavid du Colombier 
790375daca8SDavid du Colombier 	if(!typechlp[n->type->etype])
791375daca8SDavid du Colombier 		return;
792375daca8SDavid du Colombier 	switch(n->op) {
793375daca8SDavid du Colombier 	default:
794375daca8SDavid du Colombier 		return;
795375daca8SDavid du Colombier 	case OASHL:
796375daca8SDavid du Colombier 		s1 = 0;
797375daca8SDavid du Colombier 		break;
798375daca8SDavid du Colombier 	case OLSHR:
799375daca8SDavid du Colombier 		s1 = 1;
800375daca8SDavid du Colombier 		break;
801375daca8SDavid du Colombier 	case OASHR:
802375daca8SDavid du Colombier 		s1 = 2;
803375daca8SDavid du Colombier 		break;
804375daca8SDavid du Colombier 	}
805375daca8SDavid du Colombier 	if(n->right->op != OCONST)
806375daca8SDavid du Colombier 		return;
807375daca8SDavid du Colombier 	if(n->left->op != OAND)
808375daca8SDavid du Colombier 		return;
809375daca8SDavid du Colombier 	if(n->left->right->op != OCONST)
810375daca8SDavid du Colombier 		return;
811375daca8SDavid du Colombier 	switch(n->left->left->op) {
812375daca8SDavid du Colombier 	default:
813375daca8SDavid du Colombier 		return;
814375daca8SDavid du Colombier 	case OASHL:
815375daca8SDavid du Colombier 		s2 = 0;
816375daca8SDavid du Colombier 		break;
817375daca8SDavid du Colombier 	case OLSHR:
818375daca8SDavid du Colombier 		s2 = 1;
819375daca8SDavid du Colombier 		break;
820375daca8SDavid du Colombier 	case OASHR:
821375daca8SDavid du Colombier 		s2 = 2;
822375daca8SDavid du Colombier 		break;
823375daca8SDavid du Colombier 	}
824375daca8SDavid du Colombier 	if(n->left->left->right->op != OCONST)
825375daca8SDavid du Colombier 		return;
826375daca8SDavid du Colombier 
827375daca8SDavid du Colombier 	c1 = n->right->vconst;
828375daca8SDavid du Colombier 	c2 = n->left->left->right->vconst;
829375daca8SDavid du Colombier 	c3 = n->left->right->vconst;
830375daca8SDavid du Colombier 
831375daca8SDavid du Colombier /*
832375daca8SDavid du Colombier 	if(debug['h'])
833375daca8SDavid du Colombier 		print("%.3o %ld %ld %d #%.lux\n",
834375daca8SDavid du Colombier 			(s1<<3)|s2, c1, c2, topbit(c3), c3);
835375daca8SDavid du Colombier */
836375daca8SDavid du Colombier 
837375daca8SDavid du Colombier 	o = n->op;
838375daca8SDavid du Colombier 	switch((s1<<3)|s2) {
839375daca8SDavid du Colombier 	case 000:	/* (((e <<u c2) & c3) <<u c1) */
840375daca8SDavid du Colombier 		c3 >>= c2;
841375daca8SDavid du Colombier 		c1 += c2;
842375daca8SDavid du Colombier 		if(c1 >= 32)
843375daca8SDavid du Colombier 			break;
844375daca8SDavid du Colombier 		goto rewrite1;
845375daca8SDavid du Colombier 
846375daca8SDavid du Colombier 	case 002:	/* (((e >>s c2) & c3) <<u c1) */
847375daca8SDavid du Colombier 		if(topbit(c3) >= (32-c2))
848375daca8SDavid du Colombier 			break;
849375daca8SDavid du Colombier 	case 001:	/* (((e >>u c2) & c3) <<u c1) */
850375daca8SDavid du Colombier 		if(c1 > c2) {
851375daca8SDavid du Colombier 			c3 <<= c2;
852375daca8SDavid du Colombier 			c1 -= c2;
853375daca8SDavid du Colombier 			o = OASHL;
854375daca8SDavid du Colombier 			goto rewrite1;
855375daca8SDavid du Colombier 		}
856375daca8SDavid du Colombier 		c3 <<= c1;
857375daca8SDavid du Colombier 		if(c1 == c2)
858375daca8SDavid du Colombier 			goto rewrite0;
859375daca8SDavid du Colombier 		c1 = c2-c1;
860375daca8SDavid du Colombier 		o = OLSHR;
861375daca8SDavid du Colombier 		goto rewrite2;
862375daca8SDavid du Colombier 
863375daca8SDavid du Colombier 	case 022:	/* (((e >>s c2) & c3) >>s c1) */
864375daca8SDavid du Colombier 		if(c2 <= 0)
865375daca8SDavid du Colombier 			break;
866375daca8SDavid du Colombier 	case 012:	/* (((e >>s c2) & c3) >>u c1) */
867375daca8SDavid du Colombier 		if(topbit(c3) >= (32-c2))
868375daca8SDavid du Colombier 			break;
869375daca8SDavid du Colombier 		goto s11;
870375daca8SDavid du Colombier 	case 021:	/* (((e >>u c2) & c3) >>s c1) */
871375daca8SDavid du Colombier 		if(topbit(c3) >= 31 && c2 <= 0)
872375daca8SDavid du Colombier 			break;
873375daca8SDavid du Colombier 		goto s11;
874375daca8SDavid du Colombier 	case 011:	/* (((e >>u c2) & c3) >>u c1) */
875375daca8SDavid du Colombier 	s11:
876375daca8SDavid du Colombier 		c3 <<= c2;
877375daca8SDavid du Colombier 		c1 += c2;
878375daca8SDavid du Colombier 		if(c1 >= 32)
879375daca8SDavid du Colombier 			break;
880375daca8SDavid du Colombier 		o = OLSHR;
881375daca8SDavid du Colombier 		goto rewrite1;
882375daca8SDavid du Colombier 
883375daca8SDavid du Colombier 	case 020:	/* (((e <<u c2) & c3) >>s c1) */
884375daca8SDavid du Colombier 		if(topbit(c3) >= 31)
885375daca8SDavid du Colombier 			break;
886375daca8SDavid du Colombier 	case 010:	/* (((e <<u c2) & c3) >>u c1) */
887375daca8SDavid du Colombier 		c3 >>= c1;
888375daca8SDavid du Colombier 		if(c1 == c2)
889375daca8SDavid du Colombier 			goto rewrite0;
890375daca8SDavid du Colombier 		if(c1 > c2) {
891375daca8SDavid du Colombier 			c1 -= c2;
892375daca8SDavid du Colombier 			goto rewrite2;
893375daca8SDavid du Colombier 		}
894375daca8SDavid du Colombier 		c1 = c2 - c1;
895375daca8SDavid du Colombier 		o = OASHL;
896375daca8SDavid du Colombier 		goto rewrite2;
897375daca8SDavid du Colombier 	}
898375daca8SDavid du Colombier 	return;
899375daca8SDavid du Colombier 
900375daca8SDavid du Colombier rewrite0:	/* get rid of both shifts */
901375daca8SDavid du Colombier if(debug['<'])prtree(n, "rewrite0");
902375daca8SDavid du Colombier 	*n = *n->left;
903375daca8SDavid du Colombier 	n->left = n->left->left;
904375daca8SDavid du Colombier 	n->right->vconst = c3;
905375daca8SDavid du Colombier 	return;
906375daca8SDavid du Colombier rewrite1:	/* get rid of lower shift */
907375daca8SDavid du Colombier if(debug['<'])prtree(n, "rewrite1");
908375daca8SDavid du Colombier 	n->left->left = n->left->left->left;
909375daca8SDavid du Colombier 	n->left->right->vconst = c3;
910375daca8SDavid du Colombier 	n->right->vconst = c1;
911375daca8SDavid du Colombier 	n->op = o;
912375daca8SDavid du Colombier 	return;
913375daca8SDavid du Colombier rewrite2:	/* get rid of upper shift */
914375daca8SDavid du Colombier if(debug['<'])prtree(n, "rewrite2");
915375daca8SDavid du Colombier 	*n = *n->left;
916375daca8SDavid du Colombier 	n->right->vconst = c3;
917375daca8SDavid du Colombier 	n->left->right->vconst = c1;
918375daca8SDavid du Colombier 	n->left->op = o;
919375daca8SDavid du Colombier }
920375daca8SDavid du Colombier 
9213e12c5d1SDavid du Colombier int
side(Node * n)9223e12c5d1SDavid du Colombier side(Node *n)
9233e12c5d1SDavid du Colombier {
9243e12c5d1SDavid du Colombier 
9253e12c5d1SDavid du Colombier loop:
9263e12c5d1SDavid du Colombier 	if(n != Z)
9273e12c5d1SDavid du Colombier 	switch(n->op) {
9283e12c5d1SDavid du Colombier 	case OCAST:
9293e12c5d1SDavid du Colombier 	case ONOT:
9303e12c5d1SDavid du Colombier 	case OADDR:
9313e12c5d1SDavid du Colombier 	case OIND:
932*40d01547SDavid du Colombier 	case OCOM:
933*40d01547SDavid du Colombier 	case ONEG:
934*40d01547SDavid du Colombier 	case OPOS:
935*40d01547SDavid du Colombier 	case OTST:
9363e12c5d1SDavid du Colombier 		n = n->left;
9373e12c5d1SDavid du Colombier 		goto loop;
9383e12c5d1SDavid du Colombier 
9393e12c5d1SDavid du Colombier 	case OCOND:
9403e12c5d1SDavid du Colombier 		if(side(n->left))
9413e12c5d1SDavid du Colombier 			break;
9423e12c5d1SDavid du Colombier 		n = n->right;
9433e12c5d1SDavid du Colombier 
9443e12c5d1SDavid du Colombier 	case OEQ:
9453e12c5d1SDavid du Colombier 	case ONE:
9463e12c5d1SDavid du Colombier 	case OLT:
9473e12c5d1SDavid du Colombier 	case OGE:
9483e12c5d1SDavid du Colombier 	case OGT:
9493e12c5d1SDavid du Colombier 	case OLE:
9503e12c5d1SDavid du Colombier 	case OADD:
9513e12c5d1SDavid du Colombier 	case OSUB:
9523e12c5d1SDavid du Colombier 	case OMUL:
9533e12c5d1SDavid du Colombier 	case OLMUL:
9543e12c5d1SDavid du Colombier 	case ODIV:
9553e12c5d1SDavid du Colombier 	case OLDIV:
9563e12c5d1SDavid du Colombier 	case OLSHR:
9573e12c5d1SDavid du Colombier 	case OASHL:
9583e12c5d1SDavid du Colombier 	case OASHR:
9593e12c5d1SDavid du Colombier 	case OAND:
9603e12c5d1SDavid du Colombier 	case OOR:
9613e12c5d1SDavid du Colombier 	case OXOR:
9623e12c5d1SDavid du Colombier 	case OMOD:
9633e12c5d1SDavid du Colombier 	case OLMOD:
9643e12c5d1SDavid du Colombier 	case OANDAND:
9653e12c5d1SDavid du Colombier 	case OOROR:
9663e12c5d1SDavid du Colombier 	case OCOMMA:
9673e12c5d1SDavid du Colombier 	case ODOT:
968*40d01547SDavid du Colombier 	case OFAS:
969*40d01547SDavid du Colombier 	case OINDEX:
9703e12c5d1SDavid du Colombier 		if(side(n->left))
9713e12c5d1SDavid du Colombier 			break;
9723e12c5d1SDavid du Colombier 		n = n->right;
9733e12c5d1SDavid du Colombier 		goto loop;
9743e12c5d1SDavid du Colombier 
9757dd7cddfSDavid du Colombier 	case OSIGN:
9763e12c5d1SDavid du Colombier 	case OSIZE:
9773e12c5d1SDavid du Colombier 	case OCONST:
9783e12c5d1SDavid du Colombier 	case OSTRING:
9793e12c5d1SDavid du Colombier 	case OLSTRING:
9803e12c5d1SDavid du Colombier 	case ONAME:
981*40d01547SDavid du Colombier 	case OREGPAIR:
982*40d01547SDavid du Colombier 	case OEXREG:
983*40d01547SDavid du Colombier 	case OREGISTER:
984*40d01547SDavid du Colombier 	case OINDREG:
9853e12c5d1SDavid du Colombier 		return 0;
9863e12c5d1SDavid du Colombier 	}
9873e12c5d1SDavid du Colombier 	return 1;
9883e12c5d1SDavid du Colombier }
9893e12c5d1SDavid du Colombier 
9903e12c5d1SDavid du Colombier int
vconst(Node * n)9913e12c5d1SDavid du Colombier vconst(Node *n)
9923e12c5d1SDavid du Colombier {
9933e12c5d1SDavid du Colombier 	int i;
9943e12c5d1SDavid du Colombier 
9953e12c5d1SDavid du Colombier 	if(n == Z)
9963e12c5d1SDavid du Colombier 		goto no;
9973e12c5d1SDavid du Colombier 	if(n->op != OCONST)
9983e12c5d1SDavid du Colombier 		goto no;
9993e12c5d1SDavid du Colombier 	if(n->type == T)
10003e12c5d1SDavid du Colombier 		goto no;
10013e12c5d1SDavid du Colombier 	switch(n->type->etype)
10023e12c5d1SDavid du Colombier 	{
10033e12c5d1SDavid du Colombier 	case TFLOAT:
10043e12c5d1SDavid du Colombier 	case TDOUBLE:
10053e12c5d1SDavid du Colombier 		i = 100;
1006219b2ee8SDavid du Colombier 		if(n->fconst > i || n->fconst < -i)
10073e12c5d1SDavid du Colombier 			goto no;
1008219b2ee8SDavid du Colombier 		i = n->fconst;
1009219b2ee8SDavid du Colombier 		if(i != n->fconst)
1010219b2ee8SDavid du Colombier 			goto no;
1011219b2ee8SDavid du Colombier 		return i;
1012219b2ee8SDavid du Colombier 
1013219b2ee8SDavid du Colombier 	case TVLONG:
1014219b2ee8SDavid du Colombier 	case TUVLONG:
1015219b2ee8SDavid du Colombier 		i = n->vconst;
1016219b2ee8SDavid du Colombier 		if(i != n->vconst)
10173e12c5d1SDavid du Colombier 			goto no;
10183e12c5d1SDavid du Colombier 		return i;
10193e12c5d1SDavid du Colombier 
10203e12c5d1SDavid du Colombier 	case TCHAR:
10213e12c5d1SDavid du Colombier 	case TUCHAR:
10223e12c5d1SDavid du Colombier 	case TSHORT:
10233e12c5d1SDavid du Colombier 	case TUSHORT:
10247dd7cddfSDavid du Colombier 	case TINT:
10257dd7cddfSDavid du Colombier 	case TUINT:
10263e12c5d1SDavid du Colombier 	case TLONG:
10273e12c5d1SDavid du Colombier 	case TULONG:
10283e12c5d1SDavid du Colombier 	case TIND:
1029219b2ee8SDavid du Colombier 		i = n->vconst;
1030219b2ee8SDavid du Colombier 		if(i != n->vconst)
10313e12c5d1SDavid du Colombier 			goto no;
10323e12c5d1SDavid du Colombier 		return i;
10333e12c5d1SDavid du Colombier 	}
10343e12c5d1SDavid du Colombier no:
10353e12c5d1SDavid du Colombier 	return -159;	/* first uninteresting constant */
10363e12c5d1SDavid du Colombier }
10373e12c5d1SDavid du Colombier 
10383e12c5d1SDavid du Colombier /*
10397dd7cddfSDavid du Colombier  * return log(n) if n is a power of 2 constant
10407dd7cddfSDavid du Colombier  */
10417dd7cddfSDavid du Colombier int
log2(uvlong v)1042282e677fSDavid du Colombier log2(uvlong v)
10437dd7cddfSDavid du Colombier {
10447dd7cddfSDavid du Colombier 	int s, i;
1045282e677fSDavid du Colombier 	uvlong m;
10467dd7cddfSDavid du Colombier 
10477dd7cddfSDavid du Colombier 	s = 0;
10487dd7cddfSDavid du Colombier 	m = MASK(8*sizeof(uvlong));
10497dd7cddfSDavid du Colombier 	for(i=32; i; i>>=1) {
10507dd7cddfSDavid du Colombier 		m >>= i;
10517dd7cddfSDavid du Colombier 		if(!(v & m)) {
10527dd7cddfSDavid du Colombier 			v >>= i;
10537dd7cddfSDavid du Colombier 			s += i;
10547dd7cddfSDavid du Colombier 		}
10557dd7cddfSDavid du Colombier 	}
10567dd7cddfSDavid du Colombier 	if(v == 1)
10577dd7cddfSDavid du Colombier 		return s;
1058282e677fSDavid du Colombier 	return -1;
1059282e677fSDavid du Colombier }
1060282e677fSDavid du Colombier 
1061282e677fSDavid du Colombier int
vlog(Node * n)1062282e677fSDavid du Colombier vlog(Node *n)
1063282e677fSDavid du Colombier {
1064282e677fSDavid du Colombier 	if(n->op != OCONST)
1065282e677fSDavid du Colombier 		goto bad;
1066282e677fSDavid du Colombier 	if(typefd[n->type->etype])
1067282e677fSDavid du Colombier 		goto bad;
1068282e677fSDavid du Colombier 
1069282e677fSDavid du Colombier 	return log2(n->vconst);
10707dd7cddfSDavid du Colombier 
10717dd7cddfSDavid du Colombier bad:
10727dd7cddfSDavid du Colombier 	return -1;
10737dd7cddfSDavid du Colombier }
10747dd7cddfSDavid du Colombier 
10757dd7cddfSDavid du Colombier int
topbit(ulong v)10767dd7cddfSDavid du Colombier topbit(ulong v)
10777dd7cddfSDavid du Colombier {
10787dd7cddfSDavid du Colombier 	int i;
10797dd7cddfSDavid du Colombier 
10807dd7cddfSDavid du Colombier 	for(i = -1; v; i++)
10817dd7cddfSDavid du Colombier 		v >>= 1;
10827dd7cddfSDavid du Colombier 	return i;
10837dd7cddfSDavid du Colombier }
10847dd7cddfSDavid du Colombier 
10857dd7cddfSDavid du Colombier /*
10863e12c5d1SDavid du Colombier  * try to cast a constant down
10873e12c5d1SDavid du Colombier  * rather than cast a variable up
10883e12c5d1SDavid du Colombier  * example:
10893e12c5d1SDavid du Colombier  *	if(c == 'a')
10903e12c5d1SDavid du Colombier  */
10913e12c5d1SDavid du Colombier void
relcon(Node * l,Node * r)10923e12c5d1SDavid du Colombier relcon(Node *l, Node *r)
10933e12c5d1SDavid du Colombier {
1094219b2ee8SDavid du Colombier 	vlong v;
10953e12c5d1SDavid du Colombier 
10963e12c5d1SDavid du Colombier 	if(l->op != OCONST)
10973e12c5d1SDavid du Colombier 		return;
10983e12c5d1SDavid du Colombier 	if(r->op != OCAST)
10993e12c5d1SDavid du Colombier 		return;
11003e12c5d1SDavid du Colombier 	if(!nilcast(r->left->type, r->type))
11013e12c5d1SDavid du Colombier 		return;
11023e12c5d1SDavid du Colombier 	switch(r->type->etype) {
11033e12c5d1SDavid du Colombier 	default:
11043e12c5d1SDavid du Colombier 		return;
11053e12c5d1SDavid du Colombier 	case TCHAR:
11063e12c5d1SDavid du Colombier 	case TUCHAR:
11073e12c5d1SDavid du Colombier 	case TSHORT:
11083e12c5d1SDavid du Colombier 	case TUSHORT:
1109219b2ee8SDavid du Colombier 		v = convvtox(l->vconst, r->type->etype);
1110219b2ee8SDavid du Colombier 		if(v != l->vconst)
11113e12c5d1SDavid du Colombier 			return;
11123e12c5d1SDavid du Colombier 		break;
11133e12c5d1SDavid du Colombier 	}
11143e12c5d1SDavid du Colombier 	l->type = r->left->type;
11153e12c5d1SDavid du Colombier 	*r = *r->left;
11163e12c5d1SDavid du Colombier }
11173e12c5d1SDavid du Colombier 
11183e12c5d1SDavid du Colombier int
relindex(int o)11193e12c5d1SDavid du Colombier relindex(int o)
11203e12c5d1SDavid du Colombier {
11213e12c5d1SDavid du Colombier 
11223e12c5d1SDavid du Colombier 	switch(o) {
11233e12c5d1SDavid du Colombier 	default:
11243e12c5d1SDavid du Colombier 		diag(Z, "bad in relindex: %O", o);
11253e12c5d1SDavid du Colombier 	case OEQ: return 0;
11263e12c5d1SDavid du Colombier 	case ONE: return 1;
11273e12c5d1SDavid du Colombier 	case OLE: return 2;
11283e12c5d1SDavid du Colombier 	case OLS: return 3;
11293e12c5d1SDavid du Colombier 	case OLT: return 4;
11303e12c5d1SDavid du Colombier 	case OLO: return 5;
11313e12c5d1SDavid du Colombier 	case OGE: return 6;
11323e12c5d1SDavid du Colombier 	case OHS: return 7;
11333e12c5d1SDavid du Colombier 	case OGT: return 8;
11343e12c5d1SDavid du Colombier 	case OHI: return 9;
11353e12c5d1SDavid du Colombier 	}
11363e12c5d1SDavid du Colombier }
11373e12c5d1SDavid du Colombier 
11383e12c5d1SDavid du Colombier Node*
invert(Node * n)11393e12c5d1SDavid du Colombier invert(Node *n)
11403e12c5d1SDavid du Colombier {
11413e12c5d1SDavid du Colombier 	Node *i;
11423e12c5d1SDavid du Colombier 
11433e12c5d1SDavid du Colombier 	if(n == Z || n->op != OLIST)
11443e12c5d1SDavid du Colombier 		return n;
11453e12c5d1SDavid du Colombier 	i = n;
11463e12c5d1SDavid du Colombier 	for(n = n->left; n != Z; n = n->left) {
11473e12c5d1SDavid du Colombier 		if(n->op != OLIST)
11483e12c5d1SDavid du Colombier 			break;
11493e12c5d1SDavid du Colombier 		i->left = n->right;
11503e12c5d1SDavid du Colombier 		n->right = i;
11513e12c5d1SDavid du Colombier 		i = n;
11523e12c5d1SDavid du Colombier 	}
11533e12c5d1SDavid du Colombier 	i->left = n;
11543e12c5d1SDavid du Colombier 	return i;
11553e12c5d1SDavid du Colombier }
11563e12c5d1SDavid du Colombier 
11573e12c5d1SDavid du Colombier int
bitno(long b)11583e12c5d1SDavid du Colombier bitno(long b)
11593e12c5d1SDavid du Colombier {
11603e12c5d1SDavid du Colombier 	int i;
11613e12c5d1SDavid du Colombier 
11623e12c5d1SDavid du Colombier 	for(i=0; i<32; i++)
11633e12c5d1SDavid du Colombier 		if(b & (1L<<i))
11643e12c5d1SDavid du Colombier 			return i;
11653e12c5d1SDavid du Colombier 	diag(Z, "bad in bitno");
11663e12c5d1SDavid du Colombier 	return 0;
11673e12c5d1SDavid du Colombier }
11683e12c5d1SDavid du Colombier 
11697dd7cddfSDavid du Colombier long
typebitor(long a,long b)11707dd7cddfSDavid du Colombier typebitor(long a, long b)
11717dd7cddfSDavid du Colombier {
11727dd7cddfSDavid du Colombier 	long c;
11737dd7cddfSDavid du Colombier 
11747dd7cddfSDavid du Colombier 	c = a | b;
11757dd7cddfSDavid du Colombier 	if(a & b)
11767dd7cddfSDavid du Colombier 		if((a & b) == BLONG)
11777dd7cddfSDavid du Colombier 			c |= BVLONG;		/* long long => vlong */
11787dd7cddfSDavid du Colombier 		else
11797dd7cddfSDavid du Colombier 			warn(Z, "once is enough: %Q", a & b);
11807dd7cddfSDavid du Colombier 	return c;
11817dd7cddfSDavid du Colombier }
11827dd7cddfSDavid du Colombier 
11833e12c5d1SDavid du Colombier void
diag(Node * n,char * fmt,...)11847dd7cddfSDavid du Colombier diag(Node *n, char *fmt, ...)
11853e12c5d1SDavid du Colombier {
11863e12c5d1SDavid du Colombier 	char buf[STRINGSZ];
11877dd7cddfSDavid du Colombier 	va_list arg;
11883e12c5d1SDavid du Colombier 
11897dd7cddfSDavid du Colombier 	va_start(arg, fmt);
11909a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
11917dd7cddfSDavid du Colombier 	va_end(arg);
119218027f8cSDavid du Colombier 	Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);
11933e12c5d1SDavid du Colombier 
119418027f8cSDavid du Colombier 	if(debug['X']){
119518027f8cSDavid du Colombier 		Bflush(&diagbuf);
11963e12c5d1SDavid du Colombier 		abort();
119718027f8cSDavid du Colombier 	}
11983e12c5d1SDavid du Colombier 	if(n != Z)
11993e12c5d1SDavid du Colombier 	if(debug['v'])
12003e12c5d1SDavid du Colombier 		prtree(n, "diagnostic");
12013e12c5d1SDavid du Colombier 
12023e12c5d1SDavid du Colombier 	nerrors++;
12033e12c5d1SDavid du Colombier 	if(nerrors > 10) {
120418027f8cSDavid du Colombier 		Bprint(&diagbuf, "too many errors\n");
12053e12c5d1SDavid du Colombier 		errorexit();
12063e12c5d1SDavid du Colombier 	}
12073e12c5d1SDavid du Colombier }
12083e12c5d1SDavid du Colombier 
12093e12c5d1SDavid du Colombier void
warn(Node * n,char * fmt,...)12107dd7cddfSDavid du Colombier warn(Node *n, char *fmt, ...)
12113e12c5d1SDavid du Colombier {
12123e12c5d1SDavid du Colombier 	char buf[STRINGSZ];
12137dd7cddfSDavid du Colombier 	va_list arg;
12143e12c5d1SDavid du Colombier 
1215178702b1SDavid du Colombier 	if(debug['w'] || debug['W']) {
12167dd7cddfSDavid du Colombier 		va_start(arg, fmt);
12179a747e4fSDavid du Colombier 		vseprint(buf, buf+sizeof(buf), fmt, arg);
12187dd7cddfSDavid du Colombier 		va_end(arg);
1219178702b1SDavid du Colombier 		if(debug['W']) {
1220178702b1SDavid du Colombier 			diag(n, "%s", buf);
1221178702b1SDavid du Colombier 			return;
1222178702b1SDavid du Colombier 		}
1223178702b1SDavid du Colombier 		Bprint(&diagbuf, "warning: %L %s\n", (n==Z)? nearln: n->lineno, buf);
12243e12c5d1SDavid du Colombier 
12253e12c5d1SDavid du Colombier 		if(n != Z)
12263e12c5d1SDavid du Colombier 		if(debug['v'])
12273e12c5d1SDavid du Colombier 			prtree(n, "warning");
12283e12c5d1SDavid du Colombier 	}
12293e12c5d1SDavid du Colombier }
12303e12c5d1SDavid du Colombier 
12313e12c5d1SDavid du Colombier void
yyerror(char * fmt,...)12327dd7cddfSDavid du Colombier yyerror(char *fmt, ...)
12333e12c5d1SDavid du Colombier {
12343e12c5d1SDavid du Colombier 	char buf[STRINGSZ];
12357dd7cddfSDavid du Colombier 	va_list arg;
12363e12c5d1SDavid du Colombier 
12373e12c5d1SDavid du Colombier 	/*
12383e12c5d1SDavid du Colombier 	 * hack to intercept message from yaccpar
12393e12c5d1SDavid du Colombier 	 */
12407dd7cddfSDavid du Colombier 	if(strcmp(fmt, "syntax error") == 0) {
12413e12c5d1SDavid du Colombier 		yyerror("syntax error, last name: %s", symb);
12423e12c5d1SDavid du Colombier 		return;
12433e12c5d1SDavid du Colombier 	}
12447dd7cddfSDavid du Colombier 	va_start(arg, fmt);
12459a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
12467dd7cddfSDavid du Colombier 	va_end(arg);
124718027f8cSDavid du Colombier 	Bprint(&diagbuf, "%L %s\n", lineno, buf);
12483e12c5d1SDavid du Colombier 	nerrors++;
12493e12c5d1SDavid du Colombier 	if(nerrors > 10) {
125018027f8cSDavid du Colombier 		Bprint(&diagbuf, "too many errors\n");
12513e12c5d1SDavid du Colombier 		errorexit();
12523e12c5d1SDavid du Colombier 	}
12533e12c5d1SDavid du Colombier }
12543e12c5d1SDavid du Colombier 
1255375daca8SDavid du Colombier void
fatal(Node * n,char * fmt,...)1256375daca8SDavid du Colombier fatal(Node *n, char *fmt, ...)
1257375daca8SDavid du Colombier {
1258375daca8SDavid du Colombier 	char buf[STRINGSZ];
1259375daca8SDavid du Colombier 	va_list arg;
1260375daca8SDavid du Colombier 
1261375daca8SDavid du Colombier 	va_start(arg, fmt);
1262375daca8SDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
1263375daca8SDavid du Colombier 	va_end(arg);
126418027f8cSDavid du Colombier 	Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);
1265375daca8SDavid du Colombier 
126618027f8cSDavid du Colombier 	if(debug['X']){
126718027f8cSDavid du Colombier 		Bflush(&diagbuf);
1268375daca8SDavid du Colombier 		abort();
126918027f8cSDavid du Colombier 	}
1270375daca8SDavid du Colombier 	if(n != Z)
1271375daca8SDavid du Colombier 	if(debug['v'])
1272375daca8SDavid du Colombier 		prtree(n, "diagnostic");
1273375daca8SDavid du Colombier 
1274375daca8SDavid du Colombier 	nerrors++;
1275375daca8SDavid du Colombier 	errorexit();
1276375daca8SDavid du Colombier }
1277375daca8SDavid du Colombier 
12787dd7cddfSDavid du Colombier ulong	thash1	= 0x2edab8c9;
12797dd7cddfSDavid du Colombier ulong	thash2	= 0x1dc74fb8;
12807dd7cddfSDavid du Colombier ulong	thash3	= 0x1f241331;
12817dd7cddfSDavid du Colombier ulong	thash[NALLTYPES];
12827dd7cddfSDavid du Colombier Init	thashinit[] =
12833e12c5d1SDavid du Colombier {
12847dd7cddfSDavid du Colombier 	TXXX,		0x17527bbd,	0,
12857dd7cddfSDavid du Colombier 	TCHAR,		0x5cedd32b,	0,
12867dd7cddfSDavid du Colombier 	TUCHAR,		0x552c4454,	0,
12877dd7cddfSDavid du Colombier 	TSHORT,		0x63040b4b,	0,
12887dd7cddfSDavid du Colombier 	TUSHORT,	0x32a45878,	0,
12897dd7cddfSDavid du Colombier 	TINT,		0x4151d5bd,	0,
12907dd7cddfSDavid du Colombier 	TUINT,		0x5ae707d6,	0,
12917dd7cddfSDavid du Colombier 	TLONG,		0x5ef20f47,	0,
12927dd7cddfSDavid du Colombier 	TULONG,		0x36d8eb8f,	0,
12937dd7cddfSDavid du Colombier 	TVLONG,		0x6e5e9590,	0,
12947dd7cddfSDavid du Colombier 	TUVLONG,	0x75910105,	0,
12957dd7cddfSDavid du Colombier 	TFLOAT,		0x25fd7af1,	0,
12967dd7cddfSDavid du Colombier 	TDOUBLE,	0x7c40a1b2,	0,
12977dd7cddfSDavid du Colombier 	TIND,		0x1b832357,	0,
12987dd7cddfSDavid du Colombier 	TFUNC,		0x6babc9cb,	0,
12997dd7cddfSDavid du Colombier 	TARRAY,		0x7c50986d,	0,
13007dd7cddfSDavid du Colombier 	TVOID,		0x44112eff,	0,
13017dd7cddfSDavid du Colombier 	TSTRUCT,	0x7c2da3bf,	0,
13027dd7cddfSDavid du Colombier 	TUNION,		0x3eb25e98,	0,
13037dd7cddfSDavid du Colombier 	TENUM,		0x44b54f61,	0,
13047dd7cddfSDavid du Colombier 	TFILE,		0x19242ac3,	0,
13057dd7cddfSDavid du Colombier 	TOLD,		0x22b15988,	0,
13067dd7cddfSDavid du Colombier 	TDOT,		0x0204f6b3,	0,
13077dd7cddfSDavid du Colombier 	-1,		0,		0,
13083e12c5d1SDavid du Colombier };
13097dd7cddfSDavid du Colombier 
13107dd7cddfSDavid du Colombier char*	bnames[NALIGN];
13117dd7cddfSDavid du Colombier Init	bnamesinit[] =
13123e12c5d1SDavid du Colombier {
13137dd7cddfSDavid du Colombier 	Axxx,	0,	"Axxx",
13147dd7cddfSDavid du Colombier 	Ael1,	0,	"el1",
13157dd7cddfSDavid du Colombier 	Ael2,	0,	"el2",
13167dd7cddfSDavid du Colombier 	Asu2,	0,	"su2",
13177dd7cddfSDavid du Colombier 	Aarg0,	0,	"arg0",
13187dd7cddfSDavid du Colombier 	Aarg1,	0,	"arg1",
13197dd7cddfSDavid du Colombier 	Aarg2,	0,	"arg2",
13207dd7cddfSDavid du Colombier 	Aaut3,	0,	"aut3",
13217dd7cddfSDavid du Colombier 	-1,	0,	0,
13223e12c5d1SDavid du Colombier };
13237dd7cddfSDavid du Colombier 
13247dd7cddfSDavid du Colombier char*	tnames[NALLTYPES];
13257dd7cddfSDavid du Colombier Init	tnamesinit[] =
13263e12c5d1SDavid du Colombier {
13277dd7cddfSDavid du Colombier 	TXXX,		0,	"TXXX",
13287dd7cddfSDavid du Colombier 	TCHAR,		0,	"CHAR",
13297dd7cddfSDavid du Colombier 	TUCHAR,		0,	"UCHAR",
13307dd7cddfSDavid du Colombier 	TSHORT,		0,	"SHORT",
13317dd7cddfSDavid du Colombier 	TUSHORT,	0,	"USHORT",
13327dd7cddfSDavid du Colombier 	TINT,		0,	"INT",
13337dd7cddfSDavid du Colombier 	TUINT,		0,	"UINT",
13347dd7cddfSDavid du Colombier 	TLONG,		0,	"LONG",
13357dd7cddfSDavid du Colombier 	TULONG,		0,	"ULONG",
13367dd7cddfSDavid du Colombier 	TVLONG,		0,	"VLONG",
13377dd7cddfSDavid du Colombier 	TUVLONG,	0,	"UVLONG",
13387dd7cddfSDavid du Colombier 	TFLOAT,		0,	"FLOAT",
13397dd7cddfSDavid du Colombier 	TDOUBLE,	0,	"DOUBLE",
13407dd7cddfSDavid du Colombier 	TIND,		0,	"IND",
13417dd7cddfSDavid du Colombier 	TFUNC,		0,	"FUNC",
13427dd7cddfSDavid du Colombier 	TARRAY,		0,	"ARRAY",
13437dd7cddfSDavid du Colombier 	TVOID,		0,	"VOID",
13447dd7cddfSDavid du Colombier 	TSTRUCT,	0,	"STRUCT",
13457dd7cddfSDavid du Colombier 	TUNION,		0,	"UNION",
13467dd7cddfSDavid du Colombier 	TENUM,		0,	"ENUM",
13477dd7cddfSDavid du Colombier 	TFILE,		0,	"FILE",
13487dd7cddfSDavid du Colombier 	TOLD,		0,	"OLD",
13497dd7cddfSDavid du Colombier 	TDOT,		0,	"DOT",
13507dd7cddfSDavid du Colombier 	-1,		0,	0,
13513e12c5d1SDavid du Colombier };
13527dd7cddfSDavid du Colombier 
13537dd7cddfSDavid du Colombier char*	gnames[NGTYPES];
13547dd7cddfSDavid du Colombier Init	gnamesinit[] =
13553e12c5d1SDavid du Colombier {
13567dd7cddfSDavid du Colombier 	GXXX,			0,	"GXXX",
13577dd7cddfSDavid du Colombier 	GCONSTNT,		0,	"CONST",
13587dd7cddfSDavid du Colombier 	GVOLATILE,		0,	"VOLATILE",
13597dd7cddfSDavid du Colombier 	GVOLATILE|GCONSTNT,	0,	"CONST-VOLATILE",
13607dd7cddfSDavid du Colombier 	-1,			0,	0,
13617dd7cddfSDavid du Colombier };
13627dd7cddfSDavid du Colombier 
13637dd7cddfSDavid du Colombier char*	qnames[NALLTYPES];
13647dd7cddfSDavid du Colombier Init	qnamesinit[] =
13657dd7cddfSDavid du Colombier {
13667dd7cddfSDavid du Colombier 	TXXX,		0,	"TXXX",
13677dd7cddfSDavid du Colombier 	TCHAR,		0,	"CHAR",
13687dd7cddfSDavid du Colombier 	TUCHAR,		0,	"UCHAR",
13697dd7cddfSDavid du Colombier 	TSHORT,		0,	"SHORT",
13707dd7cddfSDavid du Colombier 	TUSHORT,	0,	"USHORT",
13717dd7cddfSDavid du Colombier 	TINT,		0,	"INT",
13727dd7cddfSDavid du Colombier 	TUINT,		0,	"UINT",
13737dd7cddfSDavid du Colombier 	TLONG,		0,	"LONG",
13747dd7cddfSDavid du Colombier 	TULONG,		0,	"ULONG",
13757dd7cddfSDavid du Colombier 	TVLONG,		0,	"VLONG",
13767dd7cddfSDavid du Colombier 	TUVLONG,	0,	"UVLONG",
13777dd7cddfSDavid du Colombier 	TFLOAT,		0,	"FLOAT",
13787dd7cddfSDavid du Colombier 	TDOUBLE,	0,	"DOUBLE",
13797dd7cddfSDavid du Colombier 	TIND,		0,	"IND",
13807dd7cddfSDavid du Colombier 	TFUNC,		0,	"FUNC",
13817dd7cddfSDavid du Colombier 	TARRAY,		0,	"ARRAY",
13827dd7cddfSDavid du Colombier 	TVOID,		0,	"VOID",
13837dd7cddfSDavid du Colombier 	TSTRUCT,	0,	"STRUCT",
13847dd7cddfSDavid du Colombier 	TUNION,		0,	"UNION",
13857dd7cddfSDavid du Colombier 	TENUM,		0,	"ENUM",
13867dd7cddfSDavid du Colombier 
13877dd7cddfSDavid du Colombier 	TAUTO,		0,	"AUTO",
13887dd7cddfSDavid du Colombier 	TEXTERN,	0,	"EXTERN",
13897dd7cddfSDavid du Colombier 	TSTATIC,	0,	"STATIC",
13907dd7cddfSDavid du Colombier 	TTYPEDEF,	0,	"TYPEDEF",
139180ee5cbfSDavid du Colombier 	TTYPESTR,	0,	"TYPESTR",
13927dd7cddfSDavid du Colombier 	TREGISTER,	0,	"REGISTER",
13937dd7cddfSDavid du Colombier 	TCONSTNT,	0,	"CONSTNT",
13947dd7cddfSDavid du Colombier 	TVOLATILE,	0,	"VOLATILE",
13957dd7cddfSDavid du Colombier 	TUNSIGNED,	0,	"UNSIGNED",
13967dd7cddfSDavid du Colombier 	TSIGNED,	0,	"SIGNED",
13977dd7cddfSDavid du Colombier 	TDOT,		0,	"DOT",
13987dd7cddfSDavid du Colombier 	TFILE,		0,	"FILE",
13997dd7cddfSDavid du Colombier 	TOLD,		0,	"OLD",
14007dd7cddfSDavid du Colombier 	-1,		0,	0,
14017dd7cddfSDavid du Colombier };
14027dd7cddfSDavid du Colombier char*	cnames[NCTYPES];
14037dd7cddfSDavid du Colombier Init	cnamesinit[] =
14047dd7cddfSDavid du Colombier {
14057dd7cddfSDavid du Colombier 	CXXX,		0,	"CXXX",
14067dd7cddfSDavid du Colombier 	CAUTO,		0,	"AUTO",
14077dd7cddfSDavid du Colombier 	CEXTERN,	0,	"EXTERN",
14087dd7cddfSDavid du Colombier 	CGLOBL,		0,	"GLOBL",
14097dd7cddfSDavid du Colombier 	CSTATIC,	0,	"STATIC",
14107dd7cddfSDavid du Colombier 	CLOCAL,		0,	"LOCAL",
14117dd7cddfSDavid du Colombier 	CTYPEDEF,	0,	"TYPEDEF",
141280ee5cbfSDavid du Colombier 	CTYPESTR,	0,	"TYPESTR",
14137dd7cddfSDavid du Colombier 	CPARAM,		0,	"PARAM",
14147dd7cddfSDavid du Colombier 	CSELEM,		0,	"SELEM",
14157dd7cddfSDavid du Colombier 	CLABEL,		0,	"LABEL",
14167dd7cddfSDavid du Colombier 	CEXREG,		0,	"EXREG",
14177dd7cddfSDavid du Colombier 	-1,		0,	0,
14187dd7cddfSDavid du Colombier };
14197dd7cddfSDavid du Colombier 
14207dd7cddfSDavid du Colombier char*	onames[OEND+1];
14217dd7cddfSDavid du Colombier Init	onamesinit[] =
14227dd7cddfSDavid du Colombier {
14237dd7cddfSDavid du Colombier 	OXXX,		0,	"OXXX",
14247dd7cddfSDavid du Colombier 	OADD,		0,	"ADD",
14257dd7cddfSDavid du Colombier 	OADDR,		0,	"ADDR",
14267dd7cddfSDavid du Colombier 	OAND,		0,	"AND",
14277dd7cddfSDavid du Colombier 	OANDAND,	0,	"ANDAND",
14287dd7cddfSDavid du Colombier 	OARRAY,		0,	"ARRAY",
14297dd7cddfSDavid du Colombier 	OAS,		0,	"AS",
14307dd7cddfSDavid du Colombier 	OASI,		0,	"ASI",
14317dd7cddfSDavid du Colombier 	OASADD,		0,	"ASADD",
14327dd7cddfSDavid du Colombier 	OASAND,		0,	"ASAND",
14337dd7cddfSDavid du Colombier 	OASASHL,	0,	"ASASHL",
14347dd7cddfSDavid du Colombier 	OASASHR,	0,	"ASASHR",
14357dd7cddfSDavid du Colombier 	OASDIV,		0,	"ASDIV",
14367dd7cddfSDavid du Colombier 	OASHL,		0,	"ASHL",
14377dd7cddfSDavid du Colombier 	OASHR,		0,	"ASHR",
14387dd7cddfSDavid du Colombier 	OASLDIV,	0,	"ASLDIV",
14397dd7cddfSDavid du Colombier 	OASLMOD,	0,	"ASLMOD",
14407dd7cddfSDavid du Colombier 	OASLMUL,	0,	"ASLMUL",
14417dd7cddfSDavid du Colombier 	OASLSHR,	0,	"ASLSHR",
14427dd7cddfSDavid du Colombier 	OASMOD,		0,	"ASMOD",
14437dd7cddfSDavid du Colombier 	OASMUL,		0,	"ASMUL",
14447dd7cddfSDavid du Colombier 	OASOR,		0,	"ASOR",
14457dd7cddfSDavid du Colombier 	OASSUB,		0,	"ASSUB",
14467dd7cddfSDavid du Colombier 	OASXOR,		0,	"ASXOR",
14477dd7cddfSDavid du Colombier 	OBIT,		0,	"BIT",
14487dd7cddfSDavid du Colombier 	OBREAK,		0,	"BREAK",
14497dd7cddfSDavid du Colombier 	OCASE,		0,	"CASE",
14507dd7cddfSDavid du Colombier 	OCAST,		0,	"CAST",
14517dd7cddfSDavid du Colombier 	OCOMMA,		0,	"COMMA",
14527dd7cddfSDavid du Colombier 	OCOND,		0,	"COND",
14537dd7cddfSDavid du Colombier 	OCONST,		0,	"CONST",
14547dd7cddfSDavid du Colombier 	OCONTINUE,	0,	"CONTINUE",
14557dd7cddfSDavid du Colombier 	ODIV,		0,	"DIV",
14567dd7cddfSDavid du Colombier 	ODOT,		0,	"DOT",
14577dd7cddfSDavid du Colombier 	ODOTDOT,	0,	"DOTDOT",
14587dd7cddfSDavid du Colombier 	ODWHILE,	0,	"DWHILE",
14597dd7cddfSDavid du Colombier 	OENUM,		0,	"ENUM",
14607dd7cddfSDavid du Colombier 	OEQ,		0,	"EQ",
14617dd7cddfSDavid du Colombier 	OFOR,		0,	"FOR",
14627dd7cddfSDavid du Colombier 	OFUNC,		0,	"FUNC",
14637dd7cddfSDavid du Colombier 	OGE,		0,	"GE",
14647dd7cddfSDavid du Colombier 	OGOTO,		0,	"GOTO",
14657dd7cddfSDavid du Colombier 	OGT,		0,	"GT",
14667dd7cddfSDavid du Colombier 	OHI,		0,	"HI",
14677dd7cddfSDavid du Colombier 	OHS,		0,	"HS",
14687dd7cddfSDavid du Colombier 	OIF,		0,	"IF",
14697dd7cddfSDavid du Colombier 	OIND,		0,	"IND",
14707dd7cddfSDavid du Colombier 	OINDREG,	0,	"INDREG",
14717dd7cddfSDavid du Colombier 	OINIT,		0,	"INIT",
14727dd7cddfSDavid du Colombier 	OLABEL,		0,	"LABEL",
14737dd7cddfSDavid du Colombier 	OLDIV,		0,	"LDIV",
14747dd7cddfSDavid du Colombier 	OLE,		0,	"LE",
14757dd7cddfSDavid du Colombier 	OLIST,		0,	"LIST",
14767dd7cddfSDavid du Colombier 	OLMOD,		0,	"LMOD",
14777dd7cddfSDavid du Colombier 	OLMUL,		0,	"LMUL",
14787dd7cddfSDavid du Colombier 	OLO,		0,	"LO",
14797dd7cddfSDavid du Colombier 	OLS,		0,	"LS",
14807dd7cddfSDavid du Colombier 	OLSHR,		0,	"LSHR",
14817dd7cddfSDavid du Colombier 	OLT,		0,	"LT",
14827dd7cddfSDavid du Colombier 	OMOD,		0,	"MOD",
14837dd7cddfSDavid du Colombier 	OMUL,		0,	"MUL",
14847dd7cddfSDavid du Colombier 	ONAME,		0,	"NAME",
14857dd7cddfSDavid du Colombier 	ONE,		0,	"NE",
14867dd7cddfSDavid du Colombier 	ONOT,		0,	"NOT",
14877dd7cddfSDavid du Colombier 	OOR,		0,	"OR",
14887dd7cddfSDavid du Colombier 	OOROR,		0,	"OROR",
14897dd7cddfSDavid du Colombier 	OPOSTDEC,	0,	"POSTDEC",
14907dd7cddfSDavid du Colombier 	OPOSTINC,	0,	"POSTINC",
14917dd7cddfSDavid du Colombier 	OPREDEC,	0,	"PREDEC",
14927dd7cddfSDavid du Colombier 	OPREINC,	0,	"PREINC",
14937dd7cddfSDavid du Colombier 	OPROTO,		0,	"PROTO",
14947dd7cddfSDavid du Colombier 	OREGISTER,	0,	"REGISTER",
14957dd7cddfSDavid du Colombier 	ORETURN,	0,	"RETURN",
14967dd7cddfSDavid du Colombier 	OSET,		0,	"SET",
14977dd7cddfSDavid du Colombier 	OSIGN,		0,	"SIGN",
14987dd7cddfSDavid du Colombier 	OSIZE,		0,	"SIZE",
14997dd7cddfSDavid du Colombier 	OSTRING,	0,	"STRING",
15007dd7cddfSDavid du Colombier 	OLSTRING,	0,	"LSTRING",
15017dd7cddfSDavid du Colombier 	OSTRUCT,	0,	"STRUCT",
15027dd7cddfSDavid du Colombier 	OSUB,		0,	"SUB",
15037dd7cddfSDavid du Colombier 	OSWITCH,	0,	"SWITCH",
15047dd7cddfSDavid du Colombier 	OUNION,		0,	"UNION",
15057dd7cddfSDavid du Colombier 	OUSED,		0,	"USED",
15067dd7cddfSDavid du Colombier 	OWHILE,		0,	"WHILE",
15077dd7cddfSDavid du Colombier 	OXOR,		0,	"XOR",
150880ee5cbfSDavid du Colombier 	OPOS,		0,	"POS",
15097dd7cddfSDavid du Colombier 	ONEG,		0,	"NEG",
15107dd7cddfSDavid du Colombier 	OCOM,		0,	"COM",
15117dd7cddfSDavid du Colombier 	OELEM,		0,	"ELEM",
15127dd7cddfSDavid du Colombier 	OTST,		0,	"TST",
15137dd7cddfSDavid du Colombier 	OINDEX,		0,	"INDEX",
15147dd7cddfSDavid du Colombier 	OFAS,		0,	"FAS",
1515da51d93aSDavid du Colombier 	OREGPAIR,	0,	"REGPAIR",
1516d40255d8SDavid du Colombier 	OEXREG,		0,	"EXREG",
15177dd7cddfSDavid du Colombier 	OEND,		0,	"END",
15187dd7cddfSDavid du Colombier 	-1,		0,	0,
15193e12c5d1SDavid du Colombier };
15203e12c5d1SDavid du Colombier 
152122a127bbSDavid du Colombier /*	OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */
15223e12c5d1SDavid du Colombier char	comrel[12] =
15233e12c5d1SDavid du Colombier {
15243e12c5d1SDavid du Colombier 	ONE, OEQ, OGT, OHI, OGE, OHS, OLT, OLO, OLE, OLS,
15253e12c5d1SDavid du Colombier };
15263e12c5d1SDavid du Colombier char	invrel[12] =
15273e12c5d1SDavid du Colombier {
15283e12c5d1SDavid du Colombier 	OEQ, ONE, OGE, OHS, OGT, OHI, OLE, OLS, OLT, OLO,
15293e12c5d1SDavid du Colombier };
15303e12c5d1SDavid du Colombier char	logrel[12] =
15313e12c5d1SDavid du Colombier {
15323e12c5d1SDavid du Colombier 	OEQ, ONE, OLS, OLS, OLO, OLO, OHS, OHS, OHI, OHI,
15333e12c5d1SDavid du Colombier };
15343e12c5d1SDavid du Colombier 
15357dd7cddfSDavid du Colombier char	typei[NTYPE];
15367dd7cddfSDavid du Colombier int	typeiinit[] =
15377dd7cddfSDavid du Colombier {
15387dd7cddfSDavid du Colombier 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TVLONG, TUVLONG, -1,
15397dd7cddfSDavid du Colombier };
15407dd7cddfSDavid du Colombier char	typeu[NTYPE];
15417dd7cddfSDavid du Colombier int	typeuinit[] =
15427dd7cddfSDavid du Colombier {
15437dd7cddfSDavid du Colombier 	TUCHAR, TUSHORT, TUINT, TULONG, TUVLONG, TIND, -1,
15447dd7cddfSDavid du Colombier };
1545219b2ee8SDavid du Colombier 
15467dd7cddfSDavid du Colombier char	typesuv[NTYPE];
15477dd7cddfSDavid du Colombier int	typesuvinit[] =
15487dd7cddfSDavid du Colombier {
15497dd7cddfSDavid du Colombier 	TVLONG, TUVLONG, TSTRUCT, TUNION, -1,
15507dd7cddfSDavid du Colombier };
15513e12c5d1SDavid du Colombier 
15527dd7cddfSDavid du Colombier char	typeilp[NTYPE];
15537dd7cddfSDavid du Colombier int	typeilpinit[] =
15547dd7cddfSDavid du Colombier {
15557dd7cddfSDavid du Colombier 	TINT, TUINT, TLONG, TULONG, TIND, -1
15567dd7cddfSDavid du Colombier };
1557219b2ee8SDavid du Colombier 
15587dd7cddfSDavid du Colombier char	typechl[NTYPE];
1559da51d93aSDavid du Colombier char	typechlv[NTYPE];
156022a127bbSDavid du Colombier char typechlvp[NTYPE];
15617dd7cddfSDavid du Colombier int	typechlinit[] =
15623e12c5d1SDavid du Colombier {
15637dd7cddfSDavid du Colombier 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1,
15643e12c5d1SDavid du Colombier };
15657dd7cddfSDavid du Colombier 
15667dd7cddfSDavid du Colombier char	typechlp[NTYPE];
15677dd7cddfSDavid du Colombier int	typechlpinit[] =
15683e12c5d1SDavid du Colombier {
15697dd7cddfSDavid du Colombier 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TIND, -1,
15703e12c5d1SDavid du Colombier };
15717dd7cddfSDavid du Colombier 
15727dd7cddfSDavid du Colombier char	typechlpfd[NTYPE];
15737dd7cddfSDavid du Colombier int	typechlpfdinit[] =
15743e12c5d1SDavid du Colombier {
15757dd7cddfSDavid du Colombier 	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TIND, -1,
15763e12c5d1SDavid du Colombier };
15777dd7cddfSDavid du Colombier 
15787dd7cddfSDavid du Colombier char	typec[NTYPE];
15797dd7cddfSDavid du Colombier int	typecinit[] =
15803e12c5d1SDavid du Colombier {
15817dd7cddfSDavid du Colombier 	TCHAR, TUCHAR, -1
15823e12c5d1SDavid du Colombier };
15837dd7cddfSDavid du Colombier 
15847dd7cddfSDavid du Colombier char	typeh[NTYPE];
15857dd7cddfSDavid du Colombier int	typehinit[] =
15863e12c5d1SDavid du Colombier {
15877dd7cddfSDavid du Colombier 	TSHORT, TUSHORT, -1,
15883e12c5d1SDavid du Colombier };
15897dd7cddfSDavid du Colombier 
15907dd7cddfSDavid du Colombier char	typeil[NTYPE];
15917dd7cddfSDavid du Colombier int	typeilinit[] =
15923e12c5d1SDavid du Colombier {
15937dd7cddfSDavid du Colombier 	TINT, TUINT, TLONG, TULONG, -1,
15943e12c5d1SDavid du Colombier };
15957dd7cddfSDavid du Colombier 
15967dd7cddfSDavid du Colombier char	typev[NTYPE];
15977dd7cddfSDavid du Colombier int	typevinit[] =
15983e12c5d1SDavid du Colombier {
15997dd7cddfSDavid du Colombier 	TVLONG,	TUVLONG, -1,
16003e12c5d1SDavid du Colombier };
16017dd7cddfSDavid du Colombier 
16027dd7cddfSDavid du Colombier char	typefd[NTYPE];
16037dd7cddfSDavid du Colombier int	typefdinit[] =
16043e12c5d1SDavid du Colombier {
16057dd7cddfSDavid du Colombier 	TFLOAT, TDOUBLE, -1,
16063e12c5d1SDavid du Colombier };
16077dd7cddfSDavid du Colombier 
16087dd7cddfSDavid du Colombier char	typeaf[NTYPE];
16097dd7cddfSDavid du Colombier int	typeafinit[] =
16103e12c5d1SDavid du Colombier {
16117dd7cddfSDavid du Colombier 	TFUNC, TARRAY, -1,
16123e12c5d1SDavid du Colombier };
16137dd7cddfSDavid du Colombier 
16147dd7cddfSDavid du Colombier char	typesu[NTYPE];
16157dd7cddfSDavid du Colombier int	typesuinit[] =
16167dd7cddfSDavid du Colombier {
16177dd7cddfSDavid du Colombier 	TSTRUCT, TUNION, -1,
16187dd7cddfSDavid du Colombier };
16197dd7cddfSDavid du Colombier 
16207dd7cddfSDavid du Colombier long	tasign[NTYPE];
16217dd7cddfSDavid du Colombier Init	tasigninit[] =
16227dd7cddfSDavid du Colombier {
16237dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER,	0,
16247dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER,	0,
16257dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER,	0,
16267dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER,	0,
16277dd7cddfSDavid du Colombier 	TINT,		BNUMBER,	0,
16287dd7cddfSDavid du Colombier 	TUINT,		BNUMBER,	0,
16297dd7cddfSDavid du Colombier 	TLONG,		BNUMBER,	0,
16307dd7cddfSDavid du Colombier 	TULONG,		BNUMBER,	0,
16317dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER,	0,
16327dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER,	0,
16337dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER,	0,
16347dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER,	0,
16357dd7cddfSDavid du Colombier 	TIND,		BIND,		0,
16367dd7cddfSDavid du Colombier 	TSTRUCT,	BSTRUCT,	0,
16377dd7cddfSDavid du Colombier 	TUNION,		BUNION,		0,
16387dd7cddfSDavid du Colombier 	-1,		0,		0,
16397dd7cddfSDavid du Colombier };
16407dd7cddfSDavid du Colombier 
16417dd7cddfSDavid du Colombier long	tasadd[NTYPE];
16427dd7cddfSDavid du Colombier Init	tasaddinit[] =
16437dd7cddfSDavid du Colombier {
16447dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER,	0,
16457dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER,	0,
16467dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER,	0,
16477dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER,	0,
16487dd7cddfSDavid du Colombier 	TINT,		BNUMBER,	0,
16497dd7cddfSDavid du Colombier 	TUINT,		BNUMBER,	0,
16507dd7cddfSDavid du Colombier 	TLONG,		BNUMBER,	0,
16517dd7cddfSDavid du Colombier 	TULONG,		BNUMBER,	0,
16527dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER,	0,
16537dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER,	0,
16547dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER,	0,
16557dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER,	0,
16567dd7cddfSDavid du Colombier 	TIND,		BINTEGER,	0,
16577dd7cddfSDavid du Colombier 	-1,		0,		0,
16587dd7cddfSDavid du Colombier };
16597dd7cddfSDavid du Colombier 
16607dd7cddfSDavid du Colombier long	tcast[NTYPE];
16617dd7cddfSDavid du Colombier Init	tcastinit[] =
16627dd7cddfSDavid du Colombier {
16637dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER|BIND|BVOID,	0,
16647dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER|BIND|BVOID,	0,
16657dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER|BIND|BVOID,	0,
16667dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER|BIND|BVOID,	0,
16677dd7cddfSDavid du Colombier 	TINT,		BNUMBER|BIND|BVOID,	0,
16687dd7cddfSDavid du Colombier 	TUINT,		BNUMBER|BIND|BVOID,	0,
16697dd7cddfSDavid du Colombier 	TLONG,		BNUMBER|BIND|BVOID,	0,
16707dd7cddfSDavid du Colombier 	TULONG,		BNUMBER|BIND|BVOID,	0,
16717dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER|BIND|BVOID,	0,
16727dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER|BIND|BVOID,	0,
16737dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER|BVOID,		0,
16747dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER|BVOID,		0,
16757dd7cddfSDavid du Colombier 	TIND,		BINTEGER|BIND|BVOID,	0,
16767dd7cddfSDavid du Colombier 	TVOID,		BVOID,			0,
16777dd7cddfSDavid du Colombier 	TSTRUCT,	BSTRUCT|BVOID,		0,
16787dd7cddfSDavid du Colombier 	TUNION,		BUNION|BVOID,		0,
16797dd7cddfSDavid du Colombier 	-1,		0,			0,
16807dd7cddfSDavid du Colombier };
16817dd7cddfSDavid du Colombier 
16827dd7cddfSDavid du Colombier long	tadd[NTYPE];
16837dd7cddfSDavid du Colombier Init	taddinit[] =
16847dd7cddfSDavid du Colombier {
16857dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER|BIND,	0,
16867dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER|BIND,	0,
16877dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER|BIND,	0,
16887dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER|BIND,	0,
16897dd7cddfSDavid du Colombier 	TINT,		BNUMBER|BIND,	0,
16907dd7cddfSDavid du Colombier 	TUINT,		BNUMBER|BIND,	0,
16917dd7cddfSDavid du Colombier 	TLONG,		BNUMBER|BIND,	0,
16927dd7cddfSDavid du Colombier 	TULONG,		BNUMBER|BIND,	0,
16937dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER|BIND,	0,
16947dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER|BIND,	0,
16957dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER,	0,
16967dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER,	0,
16977dd7cddfSDavid du Colombier 	TIND,		BINTEGER,	0,
16987dd7cddfSDavid du Colombier 	-1,		0,		0,
16997dd7cddfSDavid du Colombier };
17007dd7cddfSDavid du Colombier 
17017dd7cddfSDavid du Colombier long	tsub[NTYPE];
17027dd7cddfSDavid du Colombier Init	tsubinit[] =
17037dd7cddfSDavid du Colombier {
17047dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER,	0,
17057dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER,	0,
17067dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER,	0,
17077dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER,	0,
17087dd7cddfSDavid du Colombier 	TINT,		BNUMBER,	0,
17097dd7cddfSDavid du Colombier 	TUINT,		BNUMBER,	0,
17107dd7cddfSDavid du Colombier 	TLONG,		BNUMBER,	0,
17117dd7cddfSDavid du Colombier 	TULONG,		BNUMBER,	0,
17127dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER,	0,
17137dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER,	0,
17147dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER,	0,
17157dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER,	0,
17167dd7cddfSDavid du Colombier 	TIND,		BINTEGER|BIND,	0,
17177dd7cddfSDavid du Colombier 	-1,		0,		0,
17187dd7cddfSDavid du Colombier };
17197dd7cddfSDavid du Colombier 
17207dd7cddfSDavid du Colombier long	tmul[NTYPE];
17217dd7cddfSDavid du Colombier Init	tmulinit[] =
17227dd7cddfSDavid du Colombier {
17237dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER,	0,
17247dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER,	0,
17257dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER,	0,
17267dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER,	0,
17277dd7cddfSDavid du Colombier 	TINT,		BNUMBER,	0,
17287dd7cddfSDavid du Colombier 	TUINT,		BNUMBER,	0,
17297dd7cddfSDavid du Colombier 	TLONG,		BNUMBER,	0,
17307dd7cddfSDavid du Colombier 	TULONG,		BNUMBER,	0,
17317dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER,	0,
17327dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER,	0,
17337dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER,	0,
17347dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER,	0,
17357dd7cddfSDavid du Colombier 	-1,		0,		0,
17367dd7cddfSDavid du Colombier };
17377dd7cddfSDavid du Colombier 
17387dd7cddfSDavid du Colombier long	tand[NTYPE];
17397dd7cddfSDavid du Colombier Init	tandinit[] =
17407dd7cddfSDavid du Colombier {
17417dd7cddfSDavid du Colombier 	TCHAR,		BINTEGER,	0,
17427dd7cddfSDavid du Colombier 	TUCHAR,		BINTEGER,	0,
17437dd7cddfSDavid du Colombier 	TSHORT,		BINTEGER,	0,
17447dd7cddfSDavid du Colombier 	TUSHORT,	BINTEGER,	0,
17457dd7cddfSDavid du Colombier 	TINT,		BNUMBER,	0,
17467dd7cddfSDavid du Colombier 	TUINT,		BNUMBER,	0,
17477dd7cddfSDavid du Colombier 	TLONG,		BINTEGER,	0,
17487dd7cddfSDavid du Colombier 	TULONG,		BINTEGER,	0,
17497dd7cddfSDavid du Colombier 	TVLONG,		BINTEGER,	0,
17507dd7cddfSDavid du Colombier 	TUVLONG,	BINTEGER,	0,
17517dd7cddfSDavid du Colombier 	-1,		0,		0,
17527dd7cddfSDavid du Colombier };
17537dd7cddfSDavid du Colombier 
17547dd7cddfSDavid du Colombier long	trel[NTYPE];
17557dd7cddfSDavid du Colombier Init	trelinit[] =
17567dd7cddfSDavid du Colombier {
17577dd7cddfSDavid du Colombier 	TCHAR,		BNUMBER,	0,
17587dd7cddfSDavid du Colombier 	TUCHAR,		BNUMBER,	0,
17597dd7cddfSDavid du Colombier 	TSHORT,		BNUMBER,	0,
17607dd7cddfSDavid du Colombier 	TUSHORT,	BNUMBER,	0,
17617dd7cddfSDavid du Colombier 	TINT,		BNUMBER,	0,
17627dd7cddfSDavid du Colombier 	TUINT,		BNUMBER,	0,
17637dd7cddfSDavid du Colombier 	TLONG,		BNUMBER,	0,
17647dd7cddfSDavid du Colombier 	TULONG,		BNUMBER,	0,
17657dd7cddfSDavid du Colombier 	TVLONG,		BNUMBER,	0,
17667dd7cddfSDavid du Colombier 	TUVLONG,	BNUMBER,	0,
17677dd7cddfSDavid du Colombier 	TFLOAT,		BNUMBER,	0,
17687dd7cddfSDavid du Colombier 	TDOUBLE,	BNUMBER,	0,
17697dd7cddfSDavid du Colombier 	TIND,		BIND,		0,
17707dd7cddfSDavid du Colombier 	-1,		0,		0,
17717dd7cddfSDavid du Colombier };
17727dd7cddfSDavid du Colombier 
17733e12c5d1SDavid du Colombier long	tfunct[1] =
17743e12c5d1SDavid du Colombier {
17757dd7cddfSDavid du Colombier 	BFUNC,
17763e12c5d1SDavid du Colombier };
17777dd7cddfSDavid du Colombier 
17783e12c5d1SDavid du Colombier long	tindir[1] =
17793e12c5d1SDavid du Colombier {
17807dd7cddfSDavid du Colombier 	BIND,
17813e12c5d1SDavid du Colombier };
17827dd7cddfSDavid du Colombier 
17833e12c5d1SDavid du Colombier long	tdot[1] =
17843e12c5d1SDavid du Colombier {
17857dd7cddfSDavid du Colombier 	BSTRUCT|BUNION,
17863e12c5d1SDavid du Colombier };
17877dd7cddfSDavid du Colombier 
17883e12c5d1SDavid du Colombier long	tnot[1] =
17893e12c5d1SDavid du Colombier {
17907dd7cddfSDavid du Colombier 	BNUMBER|BIND,
17913e12c5d1SDavid du Colombier };
17927dd7cddfSDavid du Colombier 
17933e12c5d1SDavid du Colombier long	targ[1] =
17943e12c5d1SDavid du Colombier {
17957dd7cddfSDavid du Colombier 	BNUMBER|BIND|BSTRUCT|BUNION,
17963e12c5d1SDavid du Colombier };
17973e12c5d1SDavid du Colombier 
17983e12c5d1SDavid du Colombier char	tab[NTYPE][NTYPE] =
17993e12c5d1SDavid du Colombier {
18007dd7cddfSDavid du Colombier /*TXXX*/	{ 0,
18017dd7cddfSDavid du Colombier 		},
18027dd7cddfSDavid du Colombier 
18037dd7cddfSDavid du Colombier /*TCHAR*/	{ 0,	TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG,
18047dd7cddfSDavid du Colombier 			TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18057dd7cddfSDavid du Colombier 		},
18067dd7cddfSDavid du Colombier /*TUCHAR*/	{ 0,	TUCHAR, TUCHAR, TUSHORT, TUSHORT, TUINT, TUINT, TULONG,
18077dd7cddfSDavid du Colombier 			TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18087dd7cddfSDavid du Colombier 		},
18097dd7cddfSDavid du Colombier /*TSHORT*/	{ 0,	TSHORT, TUSHORT, TSHORT, TUSHORT, TINT, TUINT, TLONG,
18107dd7cddfSDavid du Colombier 			TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18117dd7cddfSDavid du Colombier 		},
18127dd7cddfSDavid du Colombier /*TUSHORT*/	{ 0,	TUSHORT, TUSHORT, TUSHORT, TUSHORT, TUINT, TUINT, TULONG,
18137dd7cddfSDavid du Colombier 			TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18147dd7cddfSDavid du Colombier 		},
18157dd7cddfSDavid du Colombier /*TINT*/	{ 0,	TINT, TUINT, TINT, TUINT, TINT, TUINT, TLONG,
18167dd7cddfSDavid du Colombier 			TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18177dd7cddfSDavid du Colombier 		},
18187dd7cddfSDavid du Colombier /*TUINT*/	{ 0,	TUINT, TUINT, TUINT, TUINT, TUINT, TUINT, TULONG,
18197dd7cddfSDavid du Colombier 			TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18207dd7cddfSDavid du Colombier 		},
18217dd7cddfSDavid du Colombier /*TLONG*/	{ 0,	TLONG, TULONG, TLONG, TULONG, TLONG, TULONG, TLONG,
18227dd7cddfSDavid du Colombier 			TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18237dd7cddfSDavid du Colombier 		},
18247dd7cddfSDavid du Colombier /*TULONG*/	{ 0,	TULONG, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG,
18257dd7cddfSDavid du Colombier 			TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18267dd7cddfSDavid du Colombier 		},
18277dd7cddfSDavid du Colombier /*TVLONG*/	{ 0,	TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG,
18287dd7cddfSDavid du Colombier 			TUVLONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18297dd7cddfSDavid du Colombier 		},
18307dd7cddfSDavid du Colombier /*TUVLONG*/	{ 0,	TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG,
18317dd7cddfSDavid du Colombier 			TUVLONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
18327dd7cddfSDavid du Colombier 		},
18337dd7cddfSDavid du Colombier /*TFLOAT*/	{ 0,	TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT,
18347dd7cddfSDavid du Colombier 			TFLOAT, TFLOAT, TFLOAT, TFLOAT, TDOUBLE, TIND,
18357dd7cddfSDavid du Colombier 		},
18367dd7cddfSDavid du Colombier /*TDOUBLE*/	{ 0,	TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE,
18377dd7cddfSDavid du Colombier 			TDOUBLE, TDOUBLE, TDOUBLE, TFLOAT, TDOUBLE, TIND,
18387dd7cddfSDavid du Colombier 		},
18397dd7cddfSDavid du Colombier /*TIND*/	{ 0,	TIND, TIND, TIND, TIND, TIND, TIND, TIND,
18407dd7cddfSDavid du Colombier 			 TIND, TIND, TIND, TIND, TIND, TIND,
18417dd7cddfSDavid du Colombier 		},
18423e12c5d1SDavid du Colombier };
18437dd7cddfSDavid du Colombier 
18447dd7cddfSDavid du Colombier void
urk(char * name,int max,int i)18457dd7cddfSDavid du Colombier urk(char *name, int max, int i)
18467dd7cddfSDavid du Colombier {
18477dd7cddfSDavid du Colombier 	if(i >= max) {
18487dd7cddfSDavid du Colombier 		fprint(2, "bad tinit: %s %d>=%d\n", name, i, max);
18497dd7cddfSDavid du Colombier 		exits("init");
18507dd7cddfSDavid du Colombier 	}
18517dd7cddfSDavid du Colombier }
18527dd7cddfSDavid du Colombier 
18537dd7cddfSDavid du Colombier void
tinit(void)18547dd7cddfSDavid du Colombier tinit(void)
18557dd7cddfSDavid du Colombier {
18564ac975e2SDavid du Colombier 	int *ip;
18577dd7cddfSDavid du Colombier 	Init *p;
18587dd7cddfSDavid du Colombier 
18597dd7cddfSDavid du Colombier 	for(p=thashinit; p->code >= 0; p++) {
18607dd7cddfSDavid du Colombier 		urk("thash", nelem(thash), p->code);
18617dd7cddfSDavid du Colombier 		thash[p->code] = p->value;
18627dd7cddfSDavid du Colombier 	}
18637dd7cddfSDavid du Colombier 	for(p=bnamesinit; p->code >= 0; p++) {
18647dd7cddfSDavid du Colombier 		urk("bnames", nelem(bnames), p->code);
18657dd7cddfSDavid du Colombier 		bnames[p->code] = p->s;
18667dd7cddfSDavid du Colombier 	}
18677dd7cddfSDavid du Colombier 	for(p=tnamesinit; p->code >= 0; p++) {
18687dd7cddfSDavid du Colombier 		urk("tnames", nelem(tnames), p->code);
18697dd7cddfSDavid du Colombier 		tnames[p->code] = p->s;
18707dd7cddfSDavid du Colombier 	}
18717dd7cddfSDavid du Colombier 	for(p=gnamesinit; p->code >= 0; p++) {
18727dd7cddfSDavid du Colombier 		urk("gnames", nelem(gnames), p->code);
18737dd7cddfSDavid du Colombier 		gnames[p->code] = p->s;
18747dd7cddfSDavid du Colombier 	}
18757dd7cddfSDavid du Colombier 	for(p=qnamesinit; p->code >= 0; p++) {
18767dd7cddfSDavid du Colombier 		urk("qnames", nelem(qnames), p->code);
18777dd7cddfSDavid du Colombier 		qnames[p->code] = p->s;
18787dd7cddfSDavid du Colombier 	}
18797dd7cddfSDavid du Colombier 	for(p=cnamesinit; p->code >= 0; p++) {
18807dd7cddfSDavid du Colombier 		urk("cnames", nelem(cnames), p->code);
18817dd7cddfSDavid du Colombier 		cnames[p->code] = p->s;
18827dd7cddfSDavid du Colombier 	}
18837dd7cddfSDavid du Colombier 	for(p=onamesinit; p->code >= 0; p++) {
18847dd7cddfSDavid du Colombier 		urk("onames", nelem(onames), p->code);
18857dd7cddfSDavid du Colombier 		onames[p->code] = p->s;
18867dd7cddfSDavid du Colombier 	}
18874ac975e2SDavid du Colombier 	for(ip=typeiinit; *ip>=0; ip++) {
18884ac975e2SDavid du Colombier 		urk("typei", nelem(typei), *ip);
18894ac975e2SDavid du Colombier 		typei[*ip] = 1;
18907dd7cddfSDavid du Colombier 	}
18914ac975e2SDavid du Colombier 	for(ip=typeuinit; *ip>=0; ip++) {
18924ac975e2SDavid du Colombier 		urk("typeu", nelem(typeu), *ip);
18934ac975e2SDavid du Colombier 		typeu[*ip] = 1;
18947dd7cddfSDavid du Colombier 	}
18954ac975e2SDavid du Colombier 	for(ip=typesuvinit; *ip>=0; ip++) {
18964ac975e2SDavid du Colombier 		urk("typesuv", nelem(typesuv), *ip);
18974ac975e2SDavid du Colombier 		typesuv[*ip] = 1;
18987dd7cddfSDavid du Colombier 	}
18994ac975e2SDavid du Colombier 	for(ip=typeilpinit; *ip>=0; ip++) {
19004ac975e2SDavid du Colombier 		urk("typeilp", nelem(typeilp), *ip);
19014ac975e2SDavid du Colombier 		typeilp[*ip] = 1;
19027dd7cddfSDavid du Colombier 	}
19034ac975e2SDavid du Colombier 	for(ip=typechlinit; *ip>=0; ip++) {
19044ac975e2SDavid du Colombier 		urk("typechl", nelem(typechl), *ip);
19054ac975e2SDavid du Colombier 		typechl[*ip] = 1;
19064ac975e2SDavid du Colombier 		typechlv[*ip] = 1;
19074ac975e2SDavid du Colombier 		typechlvp[*ip] = 1;
19087dd7cddfSDavid du Colombier 	}
19094ac975e2SDavid du Colombier 	for(ip=typechlpinit; *ip>=0; ip++) {
19104ac975e2SDavid du Colombier 		urk("typechlp", nelem(typechlp), *ip);
19114ac975e2SDavid du Colombier 		typechlp[*ip] = 1;
19124ac975e2SDavid du Colombier 		typechlvp[*ip] = 1;
19137dd7cddfSDavid du Colombier 	}
19144ac975e2SDavid du Colombier 	for(ip=typechlpfdinit; *ip>=0; ip++) {
19154ac975e2SDavid du Colombier 		urk("typechlpfd", nelem(typechlpfd), *ip);
19164ac975e2SDavid du Colombier 		typechlpfd[*ip] = 1;
19177dd7cddfSDavid du Colombier 	}
19184ac975e2SDavid du Colombier 	for(ip=typecinit; *ip>=0; ip++) {
19194ac975e2SDavid du Colombier 		urk("typec", nelem(typec), *ip);
19204ac975e2SDavid du Colombier 		typec[*ip] = 1;
19217dd7cddfSDavid du Colombier 	}
19224ac975e2SDavid du Colombier 	for(ip=typehinit; *ip>=0; ip++) {
19234ac975e2SDavid du Colombier 		urk("typeh", nelem(typeh), *ip);
19244ac975e2SDavid du Colombier 		typeh[*ip] = 1;
19257dd7cddfSDavid du Colombier 	}
19264ac975e2SDavid du Colombier 	for(ip=typeilinit; *ip>=0; ip++) {
19274ac975e2SDavid du Colombier 		urk("typeil", nelem(typeil), *ip);
19284ac975e2SDavid du Colombier 		typeil[*ip] = 1;
19297dd7cddfSDavid du Colombier 	}
19304ac975e2SDavid du Colombier 	for(ip=typevinit; *ip>=0; ip++) {
19314ac975e2SDavid du Colombier 		urk("typev", nelem(typev), *ip);
19324ac975e2SDavid du Colombier 		typev[*ip] = 1;
19334ac975e2SDavid du Colombier 		typechlv[*ip] = 1;
19344ac975e2SDavid du Colombier 		typechlvp[*ip] = 1;
19357dd7cddfSDavid du Colombier 	}
19364ac975e2SDavid du Colombier 	for(ip=typefdinit; *ip>=0; ip++) {
19374ac975e2SDavid du Colombier 		urk("typefd", nelem(typefd), *ip);
19384ac975e2SDavid du Colombier 		typefd[*ip] = 1;
19397dd7cddfSDavid du Colombier 	}
19404ac975e2SDavid du Colombier 	for(ip=typeafinit; *ip>=0; ip++) {
19414ac975e2SDavid du Colombier 		urk("typeaf", nelem(typeaf), *ip);
19424ac975e2SDavid du Colombier 		typeaf[*ip] = 1;
19437dd7cddfSDavid du Colombier 	}
19444ac975e2SDavid du Colombier 	for(ip=typesuinit; *ip >= 0; ip++) {
19454ac975e2SDavid du Colombier 		urk("typesu", nelem(typesu), *ip);
19464ac975e2SDavid du Colombier 		typesu[*ip] = 1;
19477dd7cddfSDavid du Colombier 	}
19487dd7cddfSDavid du Colombier 	for(p=tasigninit; p->code >= 0; p++) {
19497dd7cddfSDavid du Colombier 		urk("tasign", nelem(tasign), p->code);
19507dd7cddfSDavid du Colombier 		tasign[p->code] = p->value;
19517dd7cddfSDavid du Colombier 	}
19527dd7cddfSDavid du Colombier 	for(p=tasaddinit; p->code >= 0; p++) {
19537dd7cddfSDavid du Colombier 		urk("tasadd", nelem(tasadd), p->code);
19547dd7cddfSDavid du Colombier 		tasadd[p->code] = p->value;
19557dd7cddfSDavid du Colombier 	}
19567dd7cddfSDavid du Colombier 	for(p=tcastinit; p->code >= 0; p++) {
19577dd7cddfSDavid du Colombier 		urk("tcast", nelem(tcast), p->code);
19587dd7cddfSDavid du Colombier 		tcast[p->code] = p->value;
19597dd7cddfSDavid du Colombier 	}
19607dd7cddfSDavid du Colombier 	for(p=taddinit; p->code >= 0; p++) {
19617dd7cddfSDavid du Colombier 		urk("tadd", nelem(tadd), p->code);
19627dd7cddfSDavid du Colombier 		tadd[p->code] = p->value;
19637dd7cddfSDavid du Colombier 	}
19647dd7cddfSDavid du Colombier 	for(p=tsubinit; p->code >= 0; p++) {
19657dd7cddfSDavid du Colombier 		urk("tsub", nelem(tsub), p->code);
19667dd7cddfSDavid du Colombier 		tsub[p->code] = p->value;
19677dd7cddfSDavid du Colombier 	}
19687dd7cddfSDavid du Colombier 	for(p=tmulinit; p->code >= 0; p++) {
19697dd7cddfSDavid du Colombier 		urk("tmul", nelem(tmul), p->code);
19707dd7cddfSDavid du Colombier 		tmul[p->code] = p->value;
19717dd7cddfSDavid du Colombier 	}
19727dd7cddfSDavid du Colombier 	for(p=tandinit; p->code >= 0; p++) {
19737dd7cddfSDavid du Colombier 		urk("tand", nelem(tand), p->code);
19747dd7cddfSDavid du Colombier 		tand[p->code] = p->value;
19757dd7cddfSDavid du Colombier 	}
19767dd7cddfSDavid du Colombier 	for(p=trelinit; p->code >= 0; p++) {
19777dd7cddfSDavid du Colombier 		urk("trel", nelem(trel), p->code);
19787dd7cddfSDavid du Colombier 		trel[p->code] = p->value;
19797dd7cddfSDavid du Colombier 	}
19804ac975e2SDavid du Colombier 
19814ac975e2SDavid du Colombier 	/* 32-bit defaults */
19824ac975e2SDavid du Colombier 	typeword = typechlp;
19833a276d32SDavid du Colombier 	typeswitch = typechl;
19844ac975e2SDavid du Colombier 	typecmplx = typesuv;
19857dd7cddfSDavid du Colombier }
19869a747e4fSDavid du Colombier 
19874ac975e2SDavid du Colombier /*
19884ac975e2SDavid du Colombier  * return 1 if it is impossible to jump into the middle of n.
19894ac975e2SDavid du Colombier  */
19909a747e4fSDavid du Colombier static int
deadhead(Node * n,int caseok)19919a747e4fSDavid du Colombier deadhead(Node *n, int caseok)
19929a747e4fSDavid du Colombier {
19939a747e4fSDavid du Colombier loop:
19949a747e4fSDavid du Colombier 	if(n == Z)
19959a747e4fSDavid du Colombier 		return 1;
19969a747e4fSDavid du Colombier 	switch(n->op) {
19979a747e4fSDavid du Colombier 	case OLIST:
19989a747e4fSDavid du Colombier 		if(!deadhead(n->left, caseok))
19999a747e4fSDavid du Colombier 			return 0;
20009a747e4fSDavid du Colombier 	rloop:
20019a747e4fSDavid du Colombier 		n = n->right;
20029a747e4fSDavid du Colombier 		goto loop;
20039a747e4fSDavid du Colombier 
20049a747e4fSDavid du Colombier 	case ORETURN:
20059a747e4fSDavid du Colombier 		break;
20069a747e4fSDavid du Colombier 
20079a747e4fSDavid du Colombier 	case OLABEL:
20089a747e4fSDavid du Colombier 		return 0;
20099a747e4fSDavid du Colombier 
20109a747e4fSDavid du Colombier 	case OGOTO:
20119a747e4fSDavid du Colombier 		break;
20129a747e4fSDavid du Colombier 
20139a747e4fSDavid du Colombier 	case OCASE:
20149a747e4fSDavid du Colombier 		if(!caseok)
20159a747e4fSDavid du Colombier 			return 0;
20169a747e4fSDavid du Colombier 		goto rloop;
20179a747e4fSDavid du Colombier 
20189a747e4fSDavid du Colombier 	case OSWITCH:
20199a747e4fSDavid du Colombier 		return deadhead(n->right, 1);
20209a747e4fSDavid du Colombier 
20219a747e4fSDavid du Colombier 	case OWHILE:
20229a747e4fSDavid du Colombier 	case ODWHILE:
20239a747e4fSDavid du Colombier 		goto rloop;
20249a747e4fSDavid du Colombier 
20259a747e4fSDavid du Colombier 	case OFOR:
20269a747e4fSDavid du Colombier 		goto rloop;
20279a747e4fSDavid du Colombier 
20289a747e4fSDavid du Colombier 	case OCONTINUE:
20299a747e4fSDavid du Colombier 		break;
20309a747e4fSDavid du Colombier 
20319a747e4fSDavid du Colombier 	case OBREAK:
20329a747e4fSDavid du Colombier 		break;
20339a747e4fSDavid du Colombier 
20349a747e4fSDavid du Colombier 	case OIF:
20359a747e4fSDavid du Colombier 		return deadhead(n->right->left, caseok) && deadhead(n->right->right, caseok);
20369a747e4fSDavid du Colombier 
20379a747e4fSDavid du Colombier 	case OSET:
20389a747e4fSDavid du Colombier 	case OUSED:
20399a747e4fSDavid du Colombier 		break;
20409a747e4fSDavid du Colombier 	}
20419a747e4fSDavid du Colombier 	return 1;
20429a747e4fSDavid du Colombier }
20439a747e4fSDavid du Colombier 
20449a747e4fSDavid du Colombier int
deadheads(Node * c)20459a747e4fSDavid du Colombier deadheads(Node *c)
20469a747e4fSDavid du Colombier {
20479a747e4fSDavid du Colombier 	return deadhead(c->left, 0) && deadhead(c->right, 0);
20489a747e4fSDavid du Colombier }
2049ce941d97SDavid du Colombier 
2050ce941d97SDavid du Colombier int
mixedasop(Type * l,Type * r)2051ce941d97SDavid du Colombier mixedasop(Type *l, Type *r)
2052ce941d97SDavid du Colombier {
2053ce941d97SDavid du Colombier 	return !typefd[l->etype] && typefd[r->etype];
2054ce941d97SDavid du Colombier }
2055*40d01547SDavid du Colombier 
2056*40d01547SDavid du Colombier 
2057*40d01547SDavid du Colombier /*
2058*40d01547SDavid du Colombier  * (uvlong)~ul creates a ul mask with top bits zero, which is usually wrong
2059*40d01547SDavid du Colombier  * an explicit cast to ulong after ~ suppresses the diagnostic
2060*40d01547SDavid du Colombier  */
2061*40d01547SDavid du Colombier int
castucom(Node * r)2062*40d01547SDavid du Colombier castucom(Node *r)
2063*40d01547SDavid du Colombier {
2064*40d01547SDavid du Colombier 	Node *rl;
2065*40d01547SDavid du Colombier 
2066*40d01547SDavid du Colombier 	if(r->op == OCAST &&
2067*40d01547SDavid du Colombier 	   (rl = r->left)->op == OCOM &&
2068*40d01547SDavid du Colombier 	   (r->type->etype == TVLONG || r->type->etype == TUVLONG) &&
2069*40d01547SDavid du Colombier 	   typeu[rl->type->etype] && typechl[rl->type->etype])
2070*40d01547SDavid du Colombier 		return 1;
2071*40d01547SDavid du Colombier 	return 0;
2072*40d01547SDavid du Colombier }
2073