xref: /inferno-os/utils/8c/sgen.c (revision 45a20ab721a513710138340faff3d59a31c3e01e)
174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth void
noretval(int n)474a4d8c2SCharles.Forsyth noretval(int n)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 
774a4d8c2SCharles.Forsyth 	if(n & 1) {
874a4d8c2SCharles.Forsyth 		gins(ANOP, Z, Z);
974a4d8c2SCharles.Forsyth 		p->to.type = REGRET;
1074a4d8c2SCharles.Forsyth 	}
1174a4d8c2SCharles.Forsyth 	if(n & 2) {
1274a4d8c2SCharles.Forsyth 		gins(ANOP, Z, Z);
1374a4d8c2SCharles.Forsyth 		p->to.type = FREGRET;
1474a4d8c2SCharles.Forsyth 	}
15c0927006Sforsyth 	if((n&3) == 3)
16c0927006Sforsyth 	if(thisfn && thisfn->link && typefd[thisfn->link->etype])
17c0927006Sforsyth 		gins(AFLDZ, Z, Z);
1874a4d8c2SCharles.Forsyth }
1974a4d8c2SCharles.Forsyth 
2074a4d8c2SCharles.Forsyth /* welcome to commute */
2174a4d8c2SCharles.Forsyth static void
commute(Node * n)2274a4d8c2SCharles.Forsyth commute(Node *n)
2374a4d8c2SCharles.Forsyth {
2474a4d8c2SCharles.Forsyth 	Node *l, *r;
2574a4d8c2SCharles.Forsyth 
2674a4d8c2SCharles.Forsyth 	l = n->left;
2774a4d8c2SCharles.Forsyth 	r = n->right;
2874a4d8c2SCharles.Forsyth 	if(r->complex > l->complex) {
2974a4d8c2SCharles.Forsyth 		n->left = r;
3074a4d8c2SCharles.Forsyth 		n->right = l;
3174a4d8c2SCharles.Forsyth 	}
3274a4d8c2SCharles.Forsyth }
3374a4d8c2SCharles.Forsyth 
3474a4d8c2SCharles.Forsyth void
indexshift(Node * n)3574a4d8c2SCharles.Forsyth indexshift(Node *n)
3674a4d8c2SCharles.Forsyth {
3774a4d8c2SCharles.Forsyth 	int g;
3874a4d8c2SCharles.Forsyth 
3974a4d8c2SCharles.Forsyth 	if(!typechlp[n->type->etype])
4074a4d8c2SCharles.Forsyth 		return;
4174a4d8c2SCharles.Forsyth 	simplifyshift(n);
4274a4d8c2SCharles.Forsyth 	if(n->op == OASHL && n->right->op == OCONST){
4374a4d8c2SCharles.Forsyth 		g = vconst(n->right);
4474a4d8c2SCharles.Forsyth 		if(g >= 0 && g < 4)
4574a4d8c2SCharles.Forsyth 			n->addable = 7;
4674a4d8c2SCharles.Forsyth 	}
4774a4d8c2SCharles.Forsyth }
4874a4d8c2SCharles.Forsyth 
4974a4d8c2SCharles.Forsyth /*
5074a4d8c2SCharles.Forsyth  *	calculate addressability as follows
5174a4d8c2SCharles.Forsyth  *		NAME ==> 10/11		name+value(SB/SP)
5274a4d8c2SCharles.Forsyth  *		REGISTER ==> 12		register
5374a4d8c2SCharles.Forsyth  *		CONST ==> 20		$value
5474a4d8c2SCharles.Forsyth  *		*(20) ==> 21		value
5574a4d8c2SCharles.Forsyth  *		&(10) ==> 13		$name+value(SB)
5674a4d8c2SCharles.Forsyth  *		&(11) ==> 1		$name+value(SP)
5774a4d8c2SCharles.Forsyth  *		(13) + (20) ==> 13	fold constants
5874a4d8c2SCharles.Forsyth  *		(1) + (20) ==> 1	fold constants
5974a4d8c2SCharles.Forsyth  *		*(13) ==> 10		back to name
6074a4d8c2SCharles.Forsyth  *		*(1) ==> 11		back to name
6174a4d8c2SCharles.Forsyth  *
6274a4d8c2SCharles.Forsyth  *		(20) * (X) ==> 7	multiplier in indexing
6374a4d8c2SCharles.Forsyth  *		(X,7) + (13,1) ==> 8	adder in indexing (addresses)
6474a4d8c2SCharles.Forsyth  *		(8) ==> &9(OINDEX)	index, almost addressable
6574a4d8c2SCharles.Forsyth  *
6674a4d8c2SCharles.Forsyth  *	calculate complexity (number of registers)
6774a4d8c2SCharles.Forsyth  */
6874a4d8c2SCharles.Forsyth void
xcom(Node * n)6974a4d8c2SCharles.Forsyth xcom(Node *n)
7074a4d8c2SCharles.Forsyth {
7174a4d8c2SCharles.Forsyth 	Node *l, *r;
7274a4d8c2SCharles.Forsyth 	int g;
7374a4d8c2SCharles.Forsyth 
7474a4d8c2SCharles.Forsyth 	if(n == Z)
7574a4d8c2SCharles.Forsyth 		return;
7674a4d8c2SCharles.Forsyth 	l = n->left;
7774a4d8c2SCharles.Forsyth 	r = n->right;
7874a4d8c2SCharles.Forsyth 	n->complex = 0;
7974a4d8c2SCharles.Forsyth 	n->addable = 0;
8074a4d8c2SCharles.Forsyth 	switch(n->op) {
8174a4d8c2SCharles.Forsyth 	case OCONST:
8274a4d8c2SCharles.Forsyth 		n->addable = 20;
8374a4d8c2SCharles.Forsyth 		break;
8474a4d8c2SCharles.Forsyth 
8574a4d8c2SCharles.Forsyth 	case ONAME:
8674a4d8c2SCharles.Forsyth 		n->addable = 10;
8774a4d8c2SCharles.Forsyth 		if(n->class == CPARAM || n->class == CAUTO)
8874a4d8c2SCharles.Forsyth 			n->addable = 11;
8974a4d8c2SCharles.Forsyth 		break;
9074a4d8c2SCharles.Forsyth 
91*45a20ab7Sforsyth 	case OEXREG:
92*45a20ab7Sforsyth 		n->addable = 12;
93*45a20ab7Sforsyth 		break;
94*45a20ab7Sforsyth 
9574a4d8c2SCharles.Forsyth 	case OREGISTER:
9674a4d8c2SCharles.Forsyth 		n->addable = 12;
9774a4d8c2SCharles.Forsyth 		break;
9874a4d8c2SCharles.Forsyth 
9974a4d8c2SCharles.Forsyth 	case OINDREG:
10074a4d8c2SCharles.Forsyth 		n->addable = 12;
10174a4d8c2SCharles.Forsyth 		break;
10274a4d8c2SCharles.Forsyth 
10374a4d8c2SCharles.Forsyth 	case OADDR:
10474a4d8c2SCharles.Forsyth 		xcom(l);
10574a4d8c2SCharles.Forsyth 		if(l->addable == 10)
10674a4d8c2SCharles.Forsyth 			n->addable = 13;
10774a4d8c2SCharles.Forsyth 		else
10874a4d8c2SCharles.Forsyth 		if(l->addable == 11)
10974a4d8c2SCharles.Forsyth 			n->addable = 1;
11074a4d8c2SCharles.Forsyth 		break;
11174a4d8c2SCharles.Forsyth 
11274a4d8c2SCharles.Forsyth 	case OADD:
11374a4d8c2SCharles.Forsyth 		xcom(l);
11474a4d8c2SCharles.Forsyth 		xcom(r);
11574a4d8c2SCharles.Forsyth 		if(n->type->etype != TIND)
11674a4d8c2SCharles.Forsyth 			break;
11774a4d8c2SCharles.Forsyth 
11874a4d8c2SCharles.Forsyth 		switch(r->addable) {
11974a4d8c2SCharles.Forsyth 		case 20:
12074a4d8c2SCharles.Forsyth 			switch(l->addable) {
12174a4d8c2SCharles.Forsyth 			case 1:
12274a4d8c2SCharles.Forsyth 			case 13:
12374a4d8c2SCharles.Forsyth 			commadd:
12474a4d8c2SCharles.Forsyth 				l->type = n->type;
12574a4d8c2SCharles.Forsyth 				*n = *l;
12674a4d8c2SCharles.Forsyth 				l = new(0, Z, Z);
12774a4d8c2SCharles.Forsyth 				*l = *(n->left);
12874a4d8c2SCharles.Forsyth 				l->xoffset += r->vconst;
12974a4d8c2SCharles.Forsyth 				n->left = l;
13074a4d8c2SCharles.Forsyth 				r = n->right;
13174a4d8c2SCharles.Forsyth 				goto brk;
13274a4d8c2SCharles.Forsyth 			}
13374a4d8c2SCharles.Forsyth 			break;
13474a4d8c2SCharles.Forsyth 
13574a4d8c2SCharles.Forsyth 		case 1:
13674a4d8c2SCharles.Forsyth 		case 13:
13774a4d8c2SCharles.Forsyth 		case 10:
13874a4d8c2SCharles.Forsyth 		case 11:
13974a4d8c2SCharles.Forsyth 			/* l is the base, r is the index */
14074a4d8c2SCharles.Forsyth 			if(l->addable != 20)
14174a4d8c2SCharles.Forsyth 				n->addable = 8;
14274a4d8c2SCharles.Forsyth 			break;
14374a4d8c2SCharles.Forsyth 		}
14474a4d8c2SCharles.Forsyth 		switch(l->addable) {
14574a4d8c2SCharles.Forsyth 		case 20:
14674a4d8c2SCharles.Forsyth 			switch(r->addable) {
14774a4d8c2SCharles.Forsyth 			case 13:
14874a4d8c2SCharles.Forsyth 			case 1:
14974a4d8c2SCharles.Forsyth 				r = n->left;
15074a4d8c2SCharles.Forsyth 				l = n->right;
15174a4d8c2SCharles.Forsyth 				n->left = l;
15274a4d8c2SCharles.Forsyth 				n->right = r;
15374a4d8c2SCharles.Forsyth 				goto commadd;
15474a4d8c2SCharles.Forsyth 			}
15574a4d8c2SCharles.Forsyth 			break;
15674a4d8c2SCharles.Forsyth 
15774a4d8c2SCharles.Forsyth 		case 13:
15874a4d8c2SCharles.Forsyth 		case 1:
15974a4d8c2SCharles.Forsyth 		case 10:
16074a4d8c2SCharles.Forsyth 		case 11:
16174a4d8c2SCharles.Forsyth 			/* r is the base, l is the index */
16274a4d8c2SCharles.Forsyth 			if(r->addable != 20)
16374a4d8c2SCharles.Forsyth 				n->addable = 8;
16474a4d8c2SCharles.Forsyth 			break;
16574a4d8c2SCharles.Forsyth 		}
16674a4d8c2SCharles.Forsyth 		if(n->addable == 8 && !side(n)) {
16774a4d8c2SCharles.Forsyth 			indx(n);
16874a4d8c2SCharles.Forsyth 			l = new1(OINDEX, idx.basetree, idx.regtree);
16974a4d8c2SCharles.Forsyth 			l->scale = idx.scale;
17074a4d8c2SCharles.Forsyth 			l->addable = 9;
17174a4d8c2SCharles.Forsyth 			l->complex = l->right->complex;
17274a4d8c2SCharles.Forsyth 			l->type = l->left->type;
17374a4d8c2SCharles.Forsyth 			n->op = OADDR;
17474a4d8c2SCharles.Forsyth 			n->left = l;
17574a4d8c2SCharles.Forsyth 			n->right = Z;
17674a4d8c2SCharles.Forsyth 			n->addable = 8;
17774a4d8c2SCharles.Forsyth 			break;
17874a4d8c2SCharles.Forsyth 		}
17974a4d8c2SCharles.Forsyth 		break;
18074a4d8c2SCharles.Forsyth 
18174a4d8c2SCharles.Forsyth 	case OINDEX:
18274a4d8c2SCharles.Forsyth 		xcom(l);
18374a4d8c2SCharles.Forsyth 		xcom(r);
18474a4d8c2SCharles.Forsyth 		n->addable = 9;
18574a4d8c2SCharles.Forsyth 		break;
18674a4d8c2SCharles.Forsyth 
18774a4d8c2SCharles.Forsyth 	case OIND:
18874a4d8c2SCharles.Forsyth 		xcom(l);
18974a4d8c2SCharles.Forsyth 		if(l->op == OADDR) {
19074a4d8c2SCharles.Forsyth 			l = l->left;
19174a4d8c2SCharles.Forsyth 			l->type = n->type;
19274a4d8c2SCharles.Forsyth 			*n = *l;
19374a4d8c2SCharles.Forsyth 			return;
19474a4d8c2SCharles.Forsyth 		}
19574a4d8c2SCharles.Forsyth 		switch(l->addable) {
19674a4d8c2SCharles.Forsyth 		case 20:
19774a4d8c2SCharles.Forsyth 			n->addable = 21;
19874a4d8c2SCharles.Forsyth 			break;
19974a4d8c2SCharles.Forsyth 		case 1:
20074a4d8c2SCharles.Forsyth 			n->addable = 11;
20174a4d8c2SCharles.Forsyth 			break;
20274a4d8c2SCharles.Forsyth 		case 13:
20374a4d8c2SCharles.Forsyth 			n->addable = 10;
20474a4d8c2SCharles.Forsyth 			break;
20574a4d8c2SCharles.Forsyth 		}
20674a4d8c2SCharles.Forsyth 		break;
20774a4d8c2SCharles.Forsyth 
20874a4d8c2SCharles.Forsyth 	case OASHL:
20974a4d8c2SCharles.Forsyth 		xcom(l);
21074a4d8c2SCharles.Forsyth 		xcom(r);
21174a4d8c2SCharles.Forsyth 		indexshift(n);
21274a4d8c2SCharles.Forsyth 		break;
21374a4d8c2SCharles.Forsyth 
21474a4d8c2SCharles.Forsyth 	case OMUL:
21574a4d8c2SCharles.Forsyth 	case OLMUL:
21674a4d8c2SCharles.Forsyth 		xcom(l);
21774a4d8c2SCharles.Forsyth 		xcom(r);
21874a4d8c2SCharles.Forsyth 		g = vlog(l);
21974a4d8c2SCharles.Forsyth 		if(g >= 0) {
22074a4d8c2SCharles.Forsyth 			n->left = r;
22174a4d8c2SCharles.Forsyth 			n->right = l;
22274a4d8c2SCharles.Forsyth 			l = r;
22374a4d8c2SCharles.Forsyth 			r = n->right;
22474a4d8c2SCharles.Forsyth 		}
22574a4d8c2SCharles.Forsyth 		g = vlog(r);
22674a4d8c2SCharles.Forsyth 		if(g >= 0) {
22774a4d8c2SCharles.Forsyth 			n->op = OASHL;
22874a4d8c2SCharles.Forsyth 			r->vconst = g;
22974a4d8c2SCharles.Forsyth 			r->type = types[TINT];
23074a4d8c2SCharles.Forsyth 			indexshift(n);
23174a4d8c2SCharles.Forsyth 			break;
23274a4d8c2SCharles.Forsyth 		}
23374a4d8c2SCharles.Forsyth commute(n);
23474a4d8c2SCharles.Forsyth 		break;
23574a4d8c2SCharles.Forsyth 
23674a4d8c2SCharles.Forsyth 	case OASLDIV:
23774a4d8c2SCharles.Forsyth 		xcom(l);
23874a4d8c2SCharles.Forsyth 		xcom(r);
23974a4d8c2SCharles.Forsyth 		g = vlog(r);
24074a4d8c2SCharles.Forsyth 		if(g >= 0) {
24174a4d8c2SCharles.Forsyth 			n->op = OASLSHR;
24274a4d8c2SCharles.Forsyth 			r->vconst = g;
24374a4d8c2SCharles.Forsyth 			r->type = types[TINT];
24474a4d8c2SCharles.Forsyth 		}
24574a4d8c2SCharles.Forsyth 		break;
24674a4d8c2SCharles.Forsyth 
24774a4d8c2SCharles.Forsyth 	case OLDIV:
24874a4d8c2SCharles.Forsyth 		xcom(l);
24974a4d8c2SCharles.Forsyth 		xcom(r);
25074a4d8c2SCharles.Forsyth 		g = vlog(r);
25174a4d8c2SCharles.Forsyth 		if(g >= 0) {
25274a4d8c2SCharles.Forsyth 			n->op = OLSHR;
25374a4d8c2SCharles.Forsyth 			r->vconst = g;
25474a4d8c2SCharles.Forsyth 			r->type = types[TINT];
25574a4d8c2SCharles.Forsyth 			indexshift(n);
25674a4d8c2SCharles.Forsyth 			break;
25774a4d8c2SCharles.Forsyth 		}
25874a4d8c2SCharles.Forsyth 		break;
25974a4d8c2SCharles.Forsyth 
26074a4d8c2SCharles.Forsyth 	case OASLMOD:
26174a4d8c2SCharles.Forsyth 		xcom(l);
26274a4d8c2SCharles.Forsyth 		xcom(r);
26374a4d8c2SCharles.Forsyth 		g = vlog(r);
26474a4d8c2SCharles.Forsyth 		if(g >= 0) {
26574a4d8c2SCharles.Forsyth 			n->op = OASAND;
26674a4d8c2SCharles.Forsyth 			r->vconst--;
26774a4d8c2SCharles.Forsyth 		}
26874a4d8c2SCharles.Forsyth 		break;
26974a4d8c2SCharles.Forsyth 
27074a4d8c2SCharles.Forsyth 	case OLMOD:
27174a4d8c2SCharles.Forsyth 		xcom(l);
27274a4d8c2SCharles.Forsyth 		xcom(r);
27374a4d8c2SCharles.Forsyth 		g = vlog(r);
27474a4d8c2SCharles.Forsyth 		if(g >= 0) {
27574a4d8c2SCharles.Forsyth 			n->op = OAND;
27674a4d8c2SCharles.Forsyth 			r->vconst--;
27774a4d8c2SCharles.Forsyth 		}
27874a4d8c2SCharles.Forsyth 		break;
27974a4d8c2SCharles.Forsyth 
28074a4d8c2SCharles.Forsyth 	case OASMUL:
28174a4d8c2SCharles.Forsyth 	case OASLMUL:
28274a4d8c2SCharles.Forsyth 		xcom(l);
28374a4d8c2SCharles.Forsyth 		xcom(r);
28474a4d8c2SCharles.Forsyth 		g = vlog(r);
28574a4d8c2SCharles.Forsyth 		if(g >= 0) {
28674a4d8c2SCharles.Forsyth 			n->op = OASASHL;
28774a4d8c2SCharles.Forsyth 			r->vconst = g;
28874a4d8c2SCharles.Forsyth 		}
28974a4d8c2SCharles.Forsyth 		break;
29074a4d8c2SCharles.Forsyth 
29174a4d8c2SCharles.Forsyth 	case OLSHR:
29274a4d8c2SCharles.Forsyth 	case OASHR:
29374a4d8c2SCharles.Forsyth 		xcom(l);
29474a4d8c2SCharles.Forsyth 		xcom(r);
29574a4d8c2SCharles.Forsyth 		indexshift(n);
29674a4d8c2SCharles.Forsyth 		break;
29774a4d8c2SCharles.Forsyth 
29874a4d8c2SCharles.Forsyth 	default:
29974a4d8c2SCharles.Forsyth 		if(l != Z)
30074a4d8c2SCharles.Forsyth 			xcom(l);
30174a4d8c2SCharles.Forsyth 		if(r != Z)
30274a4d8c2SCharles.Forsyth 			xcom(r);
30374a4d8c2SCharles.Forsyth 		break;
30474a4d8c2SCharles.Forsyth 	}
30574a4d8c2SCharles.Forsyth brk:
30674a4d8c2SCharles.Forsyth 	if(n->addable >= 10)
30774a4d8c2SCharles.Forsyth 		return;
30874a4d8c2SCharles.Forsyth 	if(l != Z)
30974a4d8c2SCharles.Forsyth 		n->complex = l->complex;
31074a4d8c2SCharles.Forsyth 	if(r != Z) {
31174a4d8c2SCharles.Forsyth 		if(r->complex == n->complex)
31274a4d8c2SCharles.Forsyth 			n->complex = r->complex+1;
31374a4d8c2SCharles.Forsyth 		else
31474a4d8c2SCharles.Forsyth 		if(r->complex > n->complex)
31574a4d8c2SCharles.Forsyth 			n->complex = r->complex;
31674a4d8c2SCharles.Forsyth 	}
31774a4d8c2SCharles.Forsyth 	if(n->complex == 0)
31874a4d8c2SCharles.Forsyth 		n->complex++;
31974a4d8c2SCharles.Forsyth 
32074a4d8c2SCharles.Forsyth 	if(com64(n))
32174a4d8c2SCharles.Forsyth 		return;
32274a4d8c2SCharles.Forsyth 
32374a4d8c2SCharles.Forsyth 	switch(n->op) {
32474a4d8c2SCharles.Forsyth 
32574a4d8c2SCharles.Forsyth 	case OFUNC:
32674a4d8c2SCharles.Forsyth 		n->complex = FNX;
32774a4d8c2SCharles.Forsyth 		break;
32874a4d8c2SCharles.Forsyth 
32974a4d8c2SCharles.Forsyth 	case OLMOD:
33074a4d8c2SCharles.Forsyth 	case OMOD:
33174a4d8c2SCharles.Forsyth 	case OLMUL:
33274a4d8c2SCharles.Forsyth 	case OLDIV:
33374a4d8c2SCharles.Forsyth 	case OMUL:
33474a4d8c2SCharles.Forsyth 	case ODIV:
33574a4d8c2SCharles.Forsyth 	case OASLMUL:
33674a4d8c2SCharles.Forsyth 	case OASLDIV:
33774a4d8c2SCharles.Forsyth 	case OASLMOD:
33874a4d8c2SCharles.Forsyth 	case OASMUL:
33974a4d8c2SCharles.Forsyth 	case OASDIV:
34074a4d8c2SCharles.Forsyth 	case OASMOD:
34174a4d8c2SCharles.Forsyth 		if(r->complex >= l->complex) {
34274a4d8c2SCharles.Forsyth 			n->complex = l->complex + 3;
34374a4d8c2SCharles.Forsyth 			if(r->complex > n->complex)
34474a4d8c2SCharles.Forsyth 				n->complex = r->complex;
34574a4d8c2SCharles.Forsyth 		} else {
34674a4d8c2SCharles.Forsyth 			n->complex = r->complex + 3;
34774a4d8c2SCharles.Forsyth 			if(l->complex > n->complex)
34874a4d8c2SCharles.Forsyth 				n->complex = l->complex;
34974a4d8c2SCharles.Forsyth 		}
35074a4d8c2SCharles.Forsyth 		break;
35174a4d8c2SCharles.Forsyth 
35274a4d8c2SCharles.Forsyth 	case OLSHR:
35374a4d8c2SCharles.Forsyth 	case OASHL:
35474a4d8c2SCharles.Forsyth 	case OASHR:
35574a4d8c2SCharles.Forsyth 	case OASLSHR:
35674a4d8c2SCharles.Forsyth 	case OASASHL:
35774a4d8c2SCharles.Forsyth 	case OASASHR:
35874a4d8c2SCharles.Forsyth 		if(r->complex >= l->complex) {
35974a4d8c2SCharles.Forsyth 			n->complex = l->complex + 2;
36074a4d8c2SCharles.Forsyth 			if(r->complex > n->complex)
36174a4d8c2SCharles.Forsyth 				n->complex = r->complex;
36274a4d8c2SCharles.Forsyth 		} else {
36374a4d8c2SCharles.Forsyth 			n->complex = r->complex + 2;
36474a4d8c2SCharles.Forsyth 			if(l->complex > n->complex)
36574a4d8c2SCharles.Forsyth 				n->complex = l->complex;
36674a4d8c2SCharles.Forsyth 		}
36774a4d8c2SCharles.Forsyth 		break;
36874a4d8c2SCharles.Forsyth 
36974a4d8c2SCharles.Forsyth 	case OADD:
37074a4d8c2SCharles.Forsyth 	case OXOR:
37174a4d8c2SCharles.Forsyth 	case OAND:
37274a4d8c2SCharles.Forsyth 	case OOR:
37374a4d8c2SCharles.Forsyth 		/*
37474a4d8c2SCharles.Forsyth 		 * immediate operators, make const on right
37574a4d8c2SCharles.Forsyth 		 */
37674a4d8c2SCharles.Forsyth 		if(l->op == OCONST) {
37774a4d8c2SCharles.Forsyth 			n->left = r;
37874a4d8c2SCharles.Forsyth 			n->right = l;
37974a4d8c2SCharles.Forsyth 		}
38074a4d8c2SCharles.Forsyth 		break;
38174a4d8c2SCharles.Forsyth 
38274a4d8c2SCharles.Forsyth 	case OEQ:
38374a4d8c2SCharles.Forsyth 	case ONE:
38474a4d8c2SCharles.Forsyth 	case OLE:
38574a4d8c2SCharles.Forsyth 	case OLT:
38674a4d8c2SCharles.Forsyth 	case OGE:
38774a4d8c2SCharles.Forsyth 	case OGT:
38874a4d8c2SCharles.Forsyth 	case OHI:
38974a4d8c2SCharles.Forsyth 	case OHS:
39074a4d8c2SCharles.Forsyth 	case OLO:
39174a4d8c2SCharles.Forsyth 	case OLS:
39274a4d8c2SCharles.Forsyth 		/*
39374a4d8c2SCharles.Forsyth 		 * compare operators, make const on left
39474a4d8c2SCharles.Forsyth 		 */
39574a4d8c2SCharles.Forsyth 		if(r->op == OCONST) {
39674a4d8c2SCharles.Forsyth 			n->left = r;
39774a4d8c2SCharles.Forsyth 			n->right = l;
39874a4d8c2SCharles.Forsyth 			n->op = invrel[relindex(n->op)];
39974a4d8c2SCharles.Forsyth 		}
40074a4d8c2SCharles.Forsyth 		break;
40174a4d8c2SCharles.Forsyth 	}
40274a4d8c2SCharles.Forsyth }
40374a4d8c2SCharles.Forsyth 
40474a4d8c2SCharles.Forsyth void
indx(Node * n)40574a4d8c2SCharles.Forsyth indx(Node *n)
40674a4d8c2SCharles.Forsyth {
40774a4d8c2SCharles.Forsyth 	Node *l, *r;
40874a4d8c2SCharles.Forsyth 
40974a4d8c2SCharles.Forsyth 	if(debug['x'])
41074a4d8c2SCharles.Forsyth 		prtree(n, "indx");
41174a4d8c2SCharles.Forsyth 
41274a4d8c2SCharles.Forsyth 	l = n->left;
41374a4d8c2SCharles.Forsyth 	r = n->right;
41474a4d8c2SCharles.Forsyth 	if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) {
41574a4d8c2SCharles.Forsyth 		n->right = l;
41674a4d8c2SCharles.Forsyth 		n->left = r;
41774a4d8c2SCharles.Forsyth 		l = r;
41874a4d8c2SCharles.Forsyth 		r = n->right;
41974a4d8c2SCharles.Forsyth 	}
42074a4d8c2SCharles.Forsyth 	if(l->addable != 7) {
42174a4d8c2SCharles.Forsyth 		idx.regtree = l;
42274a4d8c2SCharles.Forsyth 		idx.scale = 1;
42374a4d8c2SCharles.Forsyth 	} else
42474a4d8c2SCharles.Forsyth 	if(l->right->addable == 20) {
42574a4d8c2SCharles.Forsyth 		idx.regtree = l->left;
42674a4d8c2SCharles.Forsyth 		idx.scale = 1 << l->right->vconst;
42774a4d8c2SCharles.Forsyth 	} else
42874a4d8c2SCharles.Forsyth 	if(l->left->addable == 20) {
42974a4d8c2SCharles.Forsyth 		idx.regtree = l->right;
43074a4d8c2SCharles.Forsyth 		idx.scale = 1 << l->left->vconst;
43174a4d8c2SCharles.Forsyth 	} else
43274a4d8c2SCharles.Forsyth 		diag(n, "bad index");
43374a4d8c2SCharles.Forsyth 
43474a4d8c2SCharles.Forsyth 	idx.basetree = r;
43574a4d8c2SCharles.Forsyth 	if(debug['x']) {
43674a4d8c2SCharles.Forsyth 		print("scale = %d\n", idx.scale);
43774a4d8c2SCharles.Forsyth 		prtree(idx.regtree, "index");
43874a4d8c2SCharles.Forsyth 		prtree(idx.basetree, "base");
43974a4d8c2SCharles.Forsyth 	}
44074a4d8c2SCharles.Forsyth }
441