xref: /plan9-contrib/sys/src/cmd/8c/sgen.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
noretval(int n)43e12c5d1SDavid du Colombier noretval(int n)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier 	if(n & 1) {
83e12c5d1SDavid du Colombier 		gins(ANOP, Z, Z);
93e12c5d1SDavid du Colombier 		p->to.type = REGRET;
103e12c5d1SDavid du Colombier 	}
113e12c5d1SDavid du Colombier 	if(n & 2) {
123e12c5d1SDavid du Colombier 		gins(ANOP, Z, Z);
133e12c5d1SDavid du Colombier 		p->to.type = FREGRET;
143e12c5d1SDavid du Colombier 	}
154ac975e2SDavid du Colombier 	if((n&3) == 3)
164ac975e2SDavid du Colombier 	if(thisfn && thisfn->link && typefd[thisfn->link->etype])
174ac975e2SDavid du Colombier 		gins(AFLDZ, Z, Z);
183e12c5d1SDavid du Colombier }
193e12c5d1SDavid du Colombier 
20375daca8SDavid du Colombier /* welcome to commute */
21375daca8SDavid du Colombier static void
commute(Node * n)22375daca8SDavid du Colombier commute(Node *n)
23375daca8SDavid du Colombier {
24375daca8SDavid du Colombier 	Node *l, *r;
25375daca8SDavid du Colombier 
26375daca8SDavid du Colombier 	l = n->left;
27375daca8SDavid du Colombier 	r = n->right;
28375daca8SDavid du Colombier 	if(r->complex > l->complex) {
29375daca8SDavid du Colombier 		n->left = r;
30375daca8SDavid du Colombier 		n->right = l;
31375daca8SDavid du Colombier 	}
32375daca8SDavid du Colombier }
33375daca8SDavid du Colombier 
34375daca8SDavid du Colombier void
indexshift(Node * n)35375daca8SDavid du Colombier indexshift(Node *n)
36375daca8SDavid du Colombier {
37375daca8SDavid du Colombier 	int g;
38375daca8SDavid du Colombier 
39375daca8SDavid du Colombier 	if(!typechlp[n->type->etype])
40375daca8SDavid du Colombier 		return;
41375daca8SDavid du Colombier 	simplifyshift(n);
42375daca8SDavid du Colombier 	if(n->op == OASHL && n->right->op == OCONST){
43375daca8SDavid du Colombier 		g = vconst(n->right);
44375daca8SDavid du Colombier 		if(g >= 0 && g < 4)
45375daca8SDavid du Colombier 			n->addable = 7;
46375daca8SDavid du Colombier 	}
47375daca8SDavid du Colombier }
48375daca8SDavid du Colombier 
49*40d01547SDavid du Colombier static int
indexing(Node * n)50*40d01547SDavid du Colombier indexing(Node *n)
51*40d01547SDavid du Colombier {
52*40d01547SDavid du Colombier 	for(; n != nil; n = n->left)
53*40d01547SDavid du Colombier 	switch(n->op){
54*40d01547SDavid du Colombier 	case OSIGN:
55*40d01547SDavid du Colombier 	case OSIZE:
56*40d01547SDavid du Colombier 	case OCONST:
57*40d01547SDavid du Colombier 	case OSTRING:
58*40d01547SDavid du Colombier 	case OLSTRING:
59*40d01547SDavid du Colombier 	case ONAME:
60*40d01547SDavid du Colombier 	case OREGPAIR:
61*40d01547SDavid du Colombier 	case OREGISTER:
62*40d01547SDavid du Colombier 	case OINDREG:
63*40d01547SDavid du Colombier 		return 0;
64*40d01547SDavid du Colombier 	case OINDEX:
65*40d01547SDavid du Colombier 		return 1;
66*40d01547SDavid du Colombier 	}
67*40d01547SDavid du Colombier 	return 0;
68*40d01547SDavid du Colombier }
69*40d01547SDavid du Colombier 
70*40d01547SDavid du Colombier 
713e12c5d1SDavid du Colombier /*
723e12c5d1SDavid du Colombier  *	calculate addressability as follows
733e12c5d1SDavid du Colombier  *		NAME ==> 10/11		name+value(SB/SP)
743e12c5d1SDavid du Colombier  *		REGISTER ==> 12		register
753e12c5d1SDavid du Colombier  *		CONST ==> 20		$value
763e12c5d1SDavid du Colombier  *		*(20) ==> 21		value
773e12c5d1SDavid du Colombier  *		&(10) ==> 13		$name+value(SB)
783e12c5d1SDavid du Colombier  *		&(11) ==> 1		$name+value(SP)
793e12c5d1SDavid du Colombier  *		(13) + (20) ==> 13	fold constants
803e12c5d1SDavid du Colombier  *		(1) + (20) ==> 1	fold constants
813e12c5d1SDavid du Colombier  *		*(13) ==> 10		back to name
823e12c5d1SDavid du Colombier  *		*(1) ==> 11		back to name
833e12c5d1SDavid du Colombier  *
843e12c5d1SDavid du Colombier  *		(20) * (X) ==> 7	multiplier in indexing
853e12c5d1SDavid du Colombier  *		(X,7) + (13,1) ==> 8	adder in indexing (addresses)
863e12c5d1SDavid du Colombier  *		(8) ==> &9(OINDEX)	index, almost addressable
873e12c5d1SDavid du Colombier  *
883e12c5d1SDavid du Colombier  *	calculate complexity (number of registers)
893e12c5d1SDavid du Colombier  */
903e12c5d1SDavid du Colombier void
xcom(Node * n)913e12c5d1SDavid du Colombier xcom(Node *n)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier 	Node *l, *r;
943e12c5d1SDavid du Colombier 	int g;
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 	if(n == Z)
973e12c5d1SDavid du Colombier 		return;
983e12c5d1SDavid du Colombier 	l = n->left;
993e12c5d1SDavid du Colombier 	r = n->right;
1003e12c5d1SDavid du Colombier 	n->complex = 0;
1013e12c5d1SDavid du Colombier 	n->addable = 0;
1023e12c5d1SDavid du Colombier 	switch(n->op) {
1033e12c5d1SDavid du Colombier 	case OCONST:
1043e12c5d1SDavid du Colombier 		n->addable = 20;
1053e12c5d1SDavid du Colombier 		break;
1063e12c5d1SDavid du Colombier 
1073e12c5d1SDavid du Colombier 	case ONAME:
1083e12c5d1SDavid du Colombier 		n->addable = 10;
1093e12c5d1SDavid du Colombier 		if(n->class == CPARAM || n->class == CAUTO)
1103e12c5d1SDavid du Colombier 			n->addable = 11;
1113e12c5d1SDavid du Colombier 		break;
1123e12c5d1SDavid du Colombier 
113d40255d8SDavid du Colombier 	case OEXREG:
114d40255d8SDavid du Colombier 		n->addable = 12;
115d40255d8SDavid du Colombier 		break;
116d40255d8SDavid du Colombier 
1173e12c5d1SDavid du Colombier 	case OREGISTER:
1183e12c5d1SDavid du Colombier 		n->addable = 12;
1193e12c5d1SDavid du Colombier 		break;
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier 	case OINDREG:
1223e12c5d1SDavid du Colombier 		n->addable = 12;
1233e12c5d1SDavid du Colombier 		break;
1243e12c5d1SDavid du Colombier 
1253e12c5d1SDavid du Colombier 	case OADDR:
1263e12c5d1SDavid du Colombier 		xcom(l);
1273e12c5d1SDavid du Colombier 		if(l->addable == 10)
1283e12c5d1SDavid du Colombier 			n->addable = 13;
1293e12c5d1SDavid du Colombier 		else
1303e12c5d1SDavid du Colombier 		if(l->addable == 11)
1313e12c5d1SDavid du Colombier 			n->addable = 1;
1323e12c5d1SDavid du Colombier 		break;
1333e12c5d1SDavid du Colombier 
1343e12c5d1SDavid du Colombier 	case OADD:
1353e12c5d1SDavid du Colombier 		xcom(l);
1363e12c5d1SDavid du Colombier 		xcom(r);
1373e12c5d1SDavid du Colombier 		if(n->type->etype != TIND)
1383e12c5d1SDavid du Colombier 			break;
1393e12c5d1SDavid du Colombier 
1403e12c5d1SDavid du Colombier 		switch(r->addable) {
14180ee5cbfSDavid du Colombier 		case 20:
1423e12c5d1SDavid du Colombier 			switch(l->addable) {
1433e12c5d1SDavid du Colombier 			case 1:
14480ee5cbfSDavid du Colombier 			case 13:
14580ee5cbfSDavid du Colombier 			commadd:
14680ee5cbfSDavid du Colombier 				l->type = n->type;
14780ee5cbfSDavid du Colombier 				*n = *l;
14880ee5cbfSDavid du Colombier 				l = new(0, Z, Z);
14980ee5cbfSDavid du Colombier 				*l = *(n->left);
15080ee5cbfSDavid du Colombier 				l->xoffset += r->vconst;
15180ee5cbfSDavid du Colombier 				n->left = l;
15280ee5cbfSDavid du Colombier 				r = n->right;
1533e12c5d1SDavid du Colombier 				goto brk;
1543e12c5d1SDavid du Colombier 			}
15580ee5cbfSDavid du Colombier 			break;
1563e12c5d1SDavid du Colombier 
15780ee5cbfSDavid du Colombier 		case 1:
15880ee5cbfSDavid du Colombier 		case 13:
15980ee5cbfSDavid du Colombier 		case 10:
16080ee5cbfSDavid du Colombier 		case 11:
161375daca8SDavid du Colombier 			/* l is the base, r is the index */
16280ee5cbfSDavid du Colombier 			if(l->addable != 20)
16380ee5cbfSDavid du Colombier 				n->addable = 8;
16480ee5cbfSDavid du Colombier 			break;
16580ee5cbfSDavid du Colombier 		}
16680ee5cbfSDavid du Colombier 		switch(l->addable) {
16780ee5cbfSDavid du Colombier 		case 20:
1683e12c5d1SDavid du Colombier 			switch(r->addable) {
1693e12c5d1SDavid du Colombier 			case 13:
1703e12c5d1SDavid du Colombier 			case 1:
17180ee5cbfSDavid du Colombier 				r = n->left;
17280ee5cbfSDavid du Colombier 				l = n->right;
17380ee5cbfSDavid du Colombier 				n->left = l;
17480ee5cbfSDavid du Colombier 				n->right = r;
17580ee5cbfSDavid du Colombier 				goto commadd;
1763e12c5d1SDavid du Colombier 			}
17780ee5cbfSDavid du Colombier 			break;
17880ee5cbfSDavid du Colombier 
1793e12c5d1SDavid du Colombier 		case 13:
1803e12c5d1SDavid du Colombier 		case 1:
18180ee5cbfSDavid du Colombier 		case 10:
18280ee5cbfSDavid du Colombier 		case 11:
183375daca8SDavid du Colombier 			/* r is the base, l is the index */
18480ee5cbfSDavid du Colombier 			if(r->addable != 20)
1853e12c5d1SDavid du Colombier 				n->addable = 8;
18680ee5cbfSDavid du Colombier 			break;
1873e12c5d1SDavid du Colombier 		}
188*40d01547SDavid du Colombier 		if(n->addable == 8 && !indexing(n) && !side(n)){
1893e12c5d1SDavid du Colombier 			indx(n);
1903e12c5d1SDavid du Colombier 			l = new1(OINDEX, idx.basetree, idx.regtree);
1913e12c5d1SDavid du Colombier 			l->scale = idx.scale;
1923e12c5d1SDavid du Colombier 			l->addable = 9;
1933e12c5d1SDavid du Colombier 			l->complex = l->right->complex;
1943e12c5d1SDavid du Colombier 			l->type = l->left->type;
1953e12c5d1SDavid du Colombier 			n->op = OADDR;
1963e12c5d1SDavid du Colombier 			n->left = l;
1973e12c5d1SDavid du Colombier 			n->right = Z;
19880ee5cbfSDavid du Colombier 			n->addable = 8;
1993e12c5d1SDavid du Colombier 			break;
2003e12c5d1SDavid du Colombier 		}
2013e12c5d1SDavid du Colombier 		break;
2023e12c5d1SDavid du Colombier 
203bd389b36SDavid du Colombier 	case OINDEX:
204bd389b36SDavid du Colombier 		xcom(l);
205bd389b36SDavid du Colombier 		xcom(r);
206bd389b36SDavid du Colombier 		n->addable = 9;
207bd389b36SDavid du Colombier 		break;
208bd389b36SDavid du Colombier 
2093e12c5d1SDavid du Colombier 	case OIND:
2103e12c5d1SDavid du Colombier 		xcom(l);
2113e12c5d1SDavid du Colombier 		if(l->op == OADDR) {
2123e12c5d1SDavid du Colombier 			l = l->left;
2133e12c5d1SDavid du Colombier 			l->type = n->type;
2143e12c5d1SDavid du Colombier 			*n = *l;
2153e12c5d1SDavid du Colombier 			return;
2163e12c5d1SDavid du Colombier 		}
2173e12c5d1SDavid du Colombier 		switch(l->addable) {
2183e12c5d1SDavid du Colombier 		case 20:
2193e12c5d1SDavid du Colombier 			n->addable = 21;
2203e12c5d1SDavid du Colombier 			break;
2213e12c5d1SDavid du Colombier 		case 1:
2223e12c5d1SDavid du Colombier 			n->addable = 11;
2233e12c5d1SDavid du Colombier 			break;
2243e12c5d1SDavid du Colombier 		case 13:
2253e12c5d1SDavid du Colombier 			n->addable = 10;
2263e12c5d1SDavid du Colombier 			break;
2273e12c5d1SDavid du Colombier 		}
2283e12c5d1SDavid du Colombier 		break;
2293e12c5d1SDavid du Colombier 
2303e12c5d1SDavid du Colombier 	case OASHL:
2313e12c5d1SDavid du Colombier 		xcom(l);
2323e12c5d1SDavid du Colombier 		xcom(r);
233375daca8SDavid du Colombier 		indexshift(n);
23480ee5cbfSDavid du Colombier 		break;
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier 	case OMUL:
2373e12c5d1SDavid du Colombier 	case OLMUL:
2383e12c5d1SDavid du Colombier 		xcom(l);
2393e12c5d1SDavid du Colombier 		xcom(r);
24080ee5cbfSDavid du Colombier 		g = vlog(l);
24180ee5cbfSDavid du Colombier 		if(g >= 0) {
24280ee5cbfSDavid du Colombier 			n->left = r;
24380ee5cbfSDavid du Colombier 			n->right = l;
24480ee5cbfSDavid du Colombier 			l = r;
24580ee5cbfSDavid du Colombier 			r = n->right;
24680ee5cbfSDavid du Colombier 		}
2473e12c5d1SDavid du Colombier 		g = vlog(r);
2483e12c5d1SDavid du Colombier 		if(g >= 0) {
2493e12c5d1SDavid du Colombier 			n->op = OASHL;
250219b2ee8SDavid du Colombier 			r->vconst = g;
2517dd7cddfSDavid du Colombier 			r->type = types[TINT];
252375daca8SDavid du Colombier 			indexshift(n);
25380ee5cbfSDavid du Colombier 			break;
2543e12c5d1SDavid du Colombier 		}
255375daca8SDavid du Colombier commute(n);
2563e12c5d1SDavid du Colombier 		break;
2573e12c5d1SDavid du Colombier 
2587dd7cddfSDavid du Colombier 	case OASLDIV:
2597dd7cddfSDavid du Colombier 		xcom(l);
2607dd7cddfSDavid du Colombier 		xcom(r);
2617dd7cddfSDavid du Colombier 		g = vlog(r);
2627dd7cddfSDavid du Colombier 		if(g >= 0) {
2637dd7cddfSDavid du Colombier 			n->op = OASLSHR;
2647dd7cddfSDavid du Colombier 			r->vconst = g;
2657dd7cddfSDavid du Colombier 			r->type = types[TINT];
2667dd7cddfSDavid du Colombier 		}
2677dd7cddfSDavid du Colombier 		break;
2687dd7cddfSDavid du Colombier 
2693e12c5d1SDavid du Colombier 	case OLDIV:
2703e12c5d1SDavid du Colombier 		xcom(l);
2713e12c5d1SDavid du Colombier 		xcom(r);
2723e12c5d1SDavid du Colombier 		g = vlog(r);
2733e12c5d1SDavid du Colombier 		if(g >= 0) {
2743e12c5d1SDavid du Colombier 			n->op = OLSHR;
275219b2ee8SDavid du Colombier 			r->vconst = g;
2767dd7cddfSDavid du Colombier 			r->type = types[TINT];
277375daca8SDavid du Colombier 			indexshift(n);
27880ee5cbfSDavid du Colombier 			break;
2797dd7cddfSDavid du Colombier 		}
2807dd7cddfSDavid du Colombier 		break;
2817dd7cddfSDavid du Colombier 
2827dd7cddfSDavid du Colombier 	case OASLMOD:
2837dd7cddfSDavid du Colombier 		xcom(l);
2847dd7cddfSDavid du Colombier 		xcom(r);
2857dd7cddfSDavid du Colombier 		g = vlog(r);
2867dd7cddfSDavid du Colombier 		if(g >= 0) {
2877dd7cddfSDavid du Colombier 			n->op = OASAND;
2887dd7cddfSDavid du Colombier 			r->vconst--;
2897dd7cddfSDavid du Colombier 		}
2907dd7cddfSDavid du Colombier 		break;
2917dd7cddfSDavid du Colombier 
2927dd7cddfSDavid du Colombier 	case OLMOD:
2937dd7cddfSDavid du Colombier 		xcom(l);
2947dd7cddfSDavid du Colombier 		xcom(r);
2957dd7cddfSDavid du Colombier 		g = vlog(r);
2967dd7cddfSDavid du Colombier 		if(g >= 0) {
2977dd7cddfSDavid du Colombier 			n->op = OAND;
2987dd7cddfSDavid du Colombier 			r->vconst--;
2993e12c5d1SDavid du Colombier 		}
3003e12c5d1SDavid du Colombier 		break;
3013e12c5d1SDavid du Colombier 
3023e12c5d1SDavid du Colombier 	case OASMUL:
3033e12c5d1SDavid du Colombier 	case OASLMUL:
3043e12c5d1SDavid du Colombier 		xcom(l);
3053e12c5d1SDavid du Colombier 		xcom(r);
3063e12c5d1SDavid du Colombier 		g = vlog(r);
3073e12c5d1SDavid du Colombier 		if(g >= 0) {
3083e12c5d1SDavid du Colombier 			n->op = OASASHL;
309219b2ee8SDavid du Colombier 			r->vconst = g;
3103e12c5d1SDavid du Colombier 		}
3113e12c5d1SDavid du Colombier 		break;
3123e12c5d1SDavid du Colombier 
3137dd7cddfSDavid du Colombier 	case OLSHR:
3147dd7cddfSDavid du Colombier 	case OASHR:
3153e12c5d1SDavid du Colombier 		xcom(l);
3163e12c5d1SDavid du Colombier 		xcom(r);
317375daca8SDavid du Colombier 		indexshift(n);
3183e12c5d1SDavid du Colombier 		break;
3193e12c5d1SDavid du Colombier 
3203e12c5d1SDavid du Colombier 	default:
3213e12c5d1SDavid du Colombier 		if(l != Z)
3223e12c5d1SDavid du Colombier 			xcom(l);
3233e12c5d1SDavid du Colombier 		if(r != Z)
3243e12c5d1SDavid du Colombier 			xcom(r);
3253e12c5d1SDavid du Colombier 		break;
3263e12c5d1SDavid du Colombier 	}
3273e12c5d1SDavid du Colombier brk:
3283e12c5d1SDavid du Colombier 	if(n->addable >= 10)
3293e12c5d1SDavid du Colombier 		return;
3303e12c5d1SDavid du Colombier 	if(l != Z)
3313e12c5d1SDavid du Colombier 		n->complex = l->complex;
3323e12c5d1SDavid du Colombier 	if(r != Z) {
3333e12c5d1SDavid du Colombier 		if(r->complex == n->complex)
3343e12c5d1SDavid du Colombier 			n->complex = r->complex+1;
3353e12c5d1SDavid du Colombier 		else
3363e12c5d1SDavid du Colombier 		if(r->complex > n->complex)
3373e12c5d1SDavid du Colombier 			n->complex = r->complex;
3383e12c5d1SDavid du Colombier 	}
3393e12c5d1SDavid du Colombier 	if(n->complex == 0)
3403e12c5d1SDavid du Colombier 		n->complex++;
341219b2ee8SDavid du Colombier 
342219b2ee8SDavid du Colombier 	if(com64(n))
343219b2ee8SDavid du Colombier 		return;
344219b2ee8SDavid du Colombier 
3453e12c5d1SDavid du Colombier 	switch(n->op) {
3463e12c5d1SDavid du Colombier 
3473e12c5d1SDavid du Colombier 	case OFUNC:
3483e12c5d1SDavid du Colombier 		n->complex = FNX;
3493e12c5d1SDavid du Colombier 		break;
3503e12c5d1SDavid du Colombier 
3513e12c5d1SDavid du Colombier 	case OLMOD:
3523e12c5d1SDavid du Colombier 	case OMOD:
3533e12c5d1SDavid du Colombier 	case OLMUL:
3543e12c5d1SDavid du Colombier 	case OLDIV:
3553e12c5d1SDavid du Colombier 	case OMUL:
3563e12c5d1SDavid du Colombier 	case ODIV:
3573e12c5d1SDavid du Colombier 	case OASLMUL:
3583e12c5d1SDavid du Colombier 	case OASLDIV:
3593e12c5d1SDavid du Colombier 	case OASLMOD:
3603e12c5d1SDavid du Colombier 	case OASMUL:
3613e12c5d1SDavid du Colombier 	case OASDIV:
3623e12c5d1SDavid du Colombier 	case OASMOD:
3633e12c5d1SDavid du Colombier 		if(r->complex >= l->complex) {
3643e12c5d1SDavid du Colombier 			n->complex = l->complex + 3;
3653e12c5d1SDavid du Colombier 			if(r->complex > n->complex)
3663e12c5d1SDavid du Colombier 				n->complex = r->complex;
3673e12c5d1SDavid du Colombier 		} else {
3683e12c5d1SDavid du Colombier 			n->complex = r->complex + 3;
3693e12c5d1SDavid du Colombier 			if(l->complex > n->complex)
3703e12c5d1SDavid du Colombier 				n->complex = l->complex;
3713e12c5d1SDavid du Colombier 		}
3723e12c5d1SDavid du Colombier 		break;
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier 	case OLSHR:
3753e12c5d1SDavid du Colombier 	case OASHL:
3763e12c5d1SDavid du Colombier 	case OASHR:
3773e12c5d1SDavid du Colombier 	case OASLSHR:
3783e12c5d1SDavid du Colombier 	case OASASHL:
3793e12c5d1SDavid du Colombier 	case OASASHR:
3803e12c5d1SDavid du Colombier 		if(r->complex >= l->complex) {
3813e12c5d1SDavid du Colombier 			n->complex = l->complex + 2;
3823e12c5d1SDavid du Colombier 			if(r->complex > n->complex)
3833e12c5d1SDavid du Colombier 				n->complex = r->complex;
3843e12c5d1SDavid du Colombier 		} else {
3853e12c5d1SDavid du Colombier 			n->complex = r->complex + 2;
3863e12c5d1SDavid du Colombier 			if(l->complex > n->complex)
3873e12c5d1SDavid du Colombier 				n->complex = l->complex;
3883e12c5d1SDavid du Colombier 		}
3893e12c5d1SDavid du Colombier 		break;
3903e12c5d1SDavid du Colombier 
3913e12c5d1SDavid du Colombier 	case OADD:
3923e12c5d1SDavid du Colombier 	case OXOR:
3933e12c5d1SDavid du Colombier 	case OAND:
3943e12c5d1SDavid du Colombier 	case OOR:
3953e12c5d1SDavid du Colombier 		/*
3963e12c5d1SDavid du Colombier 		 * immediate operators, make const on right
3973e12c5d1SDavid du Colombier 		 */
3983e12c5d1SDavid du Colombier 		if(l->op == OCONST) {
3993e12c5d1SDavid du Colombier 			n->left = r;
4003e12c5d1SDavid du Colombier 			n->right = l;
4013e12c5d1SDavid du Colombier 		}
4023e12c5d1SDavid du Colombier 		break;
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier 	case OEQ:
4053e12c5d1SDavid du Colombier 	case ONE:
4063e12c5d1SDavid du Colombier 	case OLE:
4073e12c5d1SDavid du Colombier 	case OLT:
4083e12c5d1SDavid du Colombier 	case OGE:
4093e12c5d1SDavid du Colombier 	case OGT:
4103e12c5d1SDavid du Colombier 	case OHI:
4113e12c5d1SDavid du Colombier 	case OHS:
4123e12c5d1SDavid du Colombier 	case OLO:
4133e12c5d1SDavid du Colombier 	case OLS:
4143e12c5d1SDavid du Colombier 		/*
4153e12c5d1SDavid du Colombier 		 * compare operators, make const on left
4163e12c5d1SDavid du Colombier 		 */
4173e12c5d1SDavid du Colombier 		if(r->op == OCONST) {
4183e12c5d1SDavid du Colombier 			n->left = r;
4193e12c5d1SDavid du Colombier 			n->right = l;
4203e12c5d1SDavid du Colombier 			n->op = invrel[relindex(n->op)];
4213e12c5d1SDavid du Colombier 		}
4223e12c5d1SDavid du Colombier 		break;
4233e12c5d1SDavid du Colombier 	}
4243e12c5d1SDavid du Colombier }
4253e12c5d1SDavid du Colombier 
4263e12c5d1SDavid du Colombier void
indx(Node * n)4273e12c5d1SDavid du Colombier indx(Node *n)
4283e12c5d1SDavid du Colombier {
4293e12c5d1SDavid du Colombier 	Node *l, *r;
4303e12c5d1SDavid du Colombier 
4313e12c5d1SDavid du Colombier 	if(debug['x'])
4323e12c5d1SDavid du Colombier 		prtree(n, "indx");
4333e12c5d1SDavid du Colombier 
4343e12c5d1SDavid du Colombier 	l = n->left;
4353e12c5d1SDavid du Colombier 	r = n->right;
43680ee5cbfSDavid du Colombier 	if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) {
4373e12c5d1SDavid du Colombier 		n->right = l;
4383e12c5d1SDavid du Colombier 		n->left = r;
4393e12c5d1SDavid du Colombier 		l = r;
4403e12c5d1SDavid du Colombier 		r = n->right;
4413e12c5d1SDavid du Colombier 	}
4423e12c5d1SDavid du Colombier 	if(l->addable != 7) {
4433e12c5d1SDavid du Colombier 		idx.regtree = l;
4443e12c5d1SDavid du Colombier 		idx.scale = 1;
4453e12c5d1SDavid du Colombier 	} else
4463e12c5d1SDavid du Colombier 	if(l->right->addable == 20) {
4473e12c5d1SDavid du Colombier 		idx.regtree = l->left;
448219b2ee8SDavid du Colombier 		idx.scale = 1 << l->right->vconst;
4493e12c5d1SDavid du Colombier 	} else
4503e12c5d1SDavid du Colombier 	if(l->left->addable == 20) {
4513e12c5d1SDavid du Colombier 		idx.regtree = l->right;
452219b2ee8SDavid du Colombier 		idx.scale = 1 << l->left->vconst;
4533e12c5d1SDavid du Colombier 	} else
4543e12c5d1SDavid du Colombier 		diag(n, "bad index");
4553e12c5d1SDavid du Colombier 
4563e12c5d1SDavid du Colombier 	idx.basetree = r;
4573e12c5d1SDavid du Colombier 	if(debug['x']) {
4583e12c5d1SDavid du Colombier 		print("scale = %d\n", idx.scale);
4593e12c5d1SDavid du Colombier 		prtree(idx.regtree, "index");
4603e12c5d1SDavid du Colombier 		prtree(idx.basetree, "base");
4613e12c5d1SDavid du Colombier 	}
4623e12c5d1SDavid du Colombier }
463