xref: /plan9/sys/src/cmd/6c/sgen.c (revision e887ea33cf0b0f75911958e2324340660b13e9eb)
1*e887ea33SDavid du Colombier #include "gc.h"
2*e887ea33SDavid du Colombier 
3*e887ea33SDavid du Colombier void
noretval(int n)4*e887ea33SDavid du Colombier noretval(int n)
5*e887ea33SDavid du Colombier {
6*e887ea33SDavid du Colombier 
7*e887ea33SDavid du Colombier 	if(n & 1) {
8*e887ea33SDavid du Colombier 		gins(ANOP, Z, Z);
9*e887ea33SDavid du Colombier 		p->to.type = REGRET;
10*e887ea33SDavid du Colombier 	}
11*e887ea33SDavid du Colombier 	if(n & 2) {
12*e887ea33SDavid du Colombier 		gins(ANOP, Z, Z);
13*e887ea33SDavid du Colombier 		p->to.type = FREGRET;
14*e887ea33SDavid du Colombier 	}
15*e887ea33SDavid du Colombier }
16*e887ea33SDavid du Colombier 
17*e887ea33SDavid du Colombier /* welcome to commute */
18*e887ea33SDavid du Colombier static void
commute(Node * n)19*e887ea33SDavid du Colombier commute(Node *n)
20*e887ea33SDavid du Colombier {
21*e887ea33SDavid du Colombier 	Node *l, *r;
22*e887ea33SDavid du Colombier 
23*e887ea33SDavid du Colombier 	l = n->left;
24*e887ea33SDavid du Colombier 	r = n->right;
25*e887ea33SDavid du Colombier 	if(r->complex > l->complex) {
26*e887ea33SDavid du Colombier 		n->left = r;
27*e887ea33SDavid du Colombier 		n->right = l;
28*e887ea33SDavid du Colombier 	}
29*e887ea33SDavid du Colombier }
30*e887ea33SDavid du Colombier 
31*e887ea33SDavid du Colombier void
indexshift(Node * n)32*e887ea33SDavid du Colombier indexshift(Node *n)
33*e887ea33SDavid du Colombier {
34*e887ea33SDavid du Colombier 	int g;
35*e887ea33SDavid du Colombier 
36*e887ea33SDavid du Colombier 	if(!typechlpv[n->type->etype])
37*e887ea33SDavid du Colombier 		return;
38*e887ea33SDavid du Colombier 	simplifyshift(n);
39*e887ea33SDavid du Colombier 	if(n->op == OASHL && n->right->op == OCONST){
40*e887ea33SDavid du Colombier 		g = vconst(n->right);
41*e887ea33SDavid du Colombier 		if(g >= 0 && g <= 3)
42*e887ea33SDavid du Colombier 			n->addable = 7;
43*e887ea33SDavid du Colombier 	}
44*e887ea33SDavid du Colombier }
45*e887ea33SDavid du Colombier 
46*e887ea33SDavid du Colombier /*
47*e887ea33SDavid du Colombier  *	calculate addressability as follows
48*e887ea33SDavid du Colombier  *		NAME ==> 10/11		name+value(SB/SP)
49*e887ea33SDavid du Colombier  *		REGISTER ==> 12		register
50*e887ea33SDavid du Colombier  *		CONST ==> 20		$value
51*e887ea33SDavid du Colombier  *		*(20) ==> 21		value
52*e887ea33SDavid du Colombier  *		&(10) ==> 13		$name+value(SB)
53*e887ea33SDavid du Colombier  *		&(11) ==> 1		$name+value(SP)
54*e887ea33SDavid du Colombier  *		(13) + (20) ==> 13	fold constants
55*e887ea33SDavid du Colombier  *		(1) + (20) ==> 1	fold constants
56*e887ea33SDavid du Colombier  *		*(13) ==> 10		back to name
57*e887ea33SDavid du Colombier  *		*(1) ==> 11		back to name
58*e887ea33SDavid du Colombier  *
59*e887ea33SDavid du Colombier  *		(20) * (X) ==> 7	multiplier in indexing
60*e887ea33SDavid du Colombier  *		(X,7) + (13,1) ==> 8	adder in indexing (addresses)
61*e887ea33SDavid du Colombier  *		(8) ==> &9(OINDEX)	index, almost addressable
62*e887ea33SDavid du Colombier  *
63*e887ea33SDavid du Colombier  *	calculate complexity (number of registers)
64*e887ea33SDavid du Colombier  */
65*e887ea33SDavid du Colombier void
xcom(Node * n)66*e887ea33SDavid du Colombier xcom(Node *n)
67*e887ea33SDavid du Colombier {
68*e887ea33SDavid du Colombier 	Node *l, *r;
69*e887ea33SDavid du Colombier 	int g;
70*e887ea33SDavid du Colombier 
71*e887ea33SDavid du Colombier 	if(n == Z)
72*e887ea33SDavid du Colombier 		return;
73*e887ea33SDavid du Colombier 	l = n->left;
74*e887ea33SDavid du Colombier 	r = n->right;
75*e887ea33SDavid du Colombier 	n->complex = 0;
76*e887ea33SDavid du Colombier 	n->addable = 0;
77*e887ea33SDavid du Colombier 	switch(n->op) {
78*e887ea33SDavid du Colombier 	case OCONST:
79*e887ea33SDavid du Colombier 		n->addable = 20;
80*e887ea33SDavid du Colombier 		break;
81*e887ea33SDavid du Colombier 
82*e887ea33SDavid du Colombier 	case ONAME:
83*e887ea33SDavid du Colombier 		n->addable = 10;
84*e887ea33SDavid du Colombier 		if(n->class == CPARAM || n->class == CAUTO)
85*e887ea33SDavid du Colombier 			n->addable = 11;
86*e887ea33SDavid du Colombier 		break;
87*e887ea33SDavid du Colombier 
88*e887ea33SDavid du Colombier 	case OREGISTER:
89*e887ea33SDavid du Colombier 		n->addable = 12;
90*e887ea33SDavid du Colombier 		break;
91*e887ea33SDavid du Colombier 
92*e887ea33SDavid du Colombier 	case OINDREG:
93*e887ea33SDavid du Colombier 		n->addable = 12;
94*e887ea33SDavid du Colombier 		break;
95*e887ea33SDavid du Colombier 
96*e887ea33SDavid du Colombier 	case OADDR:
97*e887ea33SDavid du Colombier 		xcom(l);
98*e887ea33SDavid du Colombier 		if(l->addable == 10)
99*e887ea33SDavid du Colombier 			n->addable = 13;
100*e887ea33SDavid du Colombier 		else
101*e887ea33SDavid du Colombier 		if(l->addable == 11)
102*e887ea33SDavid du Colombier 			n->addable = 1;
103*e887ea33SDavid du Colombier 		break;
104*e887ea33SDavid du Colombier 
105*e887ea33SDavid du Colombier 	case OADD:
106*e887ea33SDavid du Colombier 		xcom(l);
107*e887ea33SDavid du Colombier 		xcom(r);
108*e887ea33SDavid du Colombier 		if(n->type->etype != TIND)
109*e887ea33SDavid du Colombier 			break;
110*e887ea33SDavid du Colombier 
111*e887ea33SDavid du Colombier 		switch(r->addable) {
112*e887ea33SDavid du Colombier 		case 20:
113*e887ea33SDavid du Colombier 			switch(l->addable) {
114*e887ea33SDavid du Colombier 			case 1:
115*e887ea33SDavid du Colombier 			case 13:
116*e887ea33SDavid du Colombier 			commadd:
117*e887ea33SDavid du Colombier 				l->type = n->type;
118*e887ea33SDavid du Colombier 				*n = *l;
119*e887ea33SDavid du Colombier 				l = new(0, Z, Z);
120*e887ea33SDavid du Colombier 				*l = *(n->left);
121*e887ea33SDavid du Colombier 				l->xoffset += r->vconst;
122*e887ea33SDavid du Colombier 				n->left = l;
123*e887ea33SDavid du Colombier 				r = n->right;
124*e887ea33SDavid du Colombier 				goto brk;
125*e887ea33SDavid du Colombier 			}
126*e887ea33SDavid du Colombier 			break;
127*e887ea33SDavid du Colombier 
128*e887ea33SDavid du Colombier 		case 1:
129*e887ea33SDavid du Colombier 		case 13:
130*e887ea33SDavid du Colombier 		case 10:
131*e887ea33SDavid du Colombier 		case 11:
132*e887ea33SDavid du Colombier 			/* l is the base, r is the index */
133*e887ea33SDavid du Colombier 			if(l->addable != 20)
134*e887ea33SDavid du Colombier 				n->addable = 8;
135*e887ea33SDavid du Colombier 			break;
136*e887ea33SDavid du Colombier 		}
137*e887ea33SDavid du Colombier 		switch(l->addable) {
138*e887ea33SDavid du Colombier 		case 20:
139*e887ea33SDavid du Colombier 			switch(r->addable) {
140*e887ea33SDavid du Colombier 			case 13:
141*e887ea33SDavid du Colombier 			case 1:
142*e887ea33SDavid du Colombier 				r = n->left;
143*e887ea33SDavid du Colombier 				l = n->right;
144*e887ea33SDavid du Colombier 				n->left = l;
145*e887ea33SDavid du Colombier 				n->right = r;
146*e887ea33SDavid du Colombier 				goto commadd;
147*e887ea33SDavid du Colombier 			}
148*e887ea33SDavid du Colombier 			break;
149*e887ea33SDavid du Colombier 
150*e887ea33SDavid du Colombier 		case 13:
151*e887ea33SDavid du Colombier 		case 1:
152*e887ea33SDavid du Colombier 		case 10:
153*e887ea33SDavid du Colombier 		case 11:
154*e887ea33SDavid du Colombier 			/* r is the base, l is the index */
155*e887ea33SDavid du Colombier 			if(r->addable != 20)
156*e887ea33SDavid du Colombier 				n->addable = 8;
157*e887ea33SDavid du Colombier 			break;
158*e887ea33SDavid du Colombier 		}
159*e887ea33SDavid du Colombier 		if(n->addable == 8 && !side(n)) {
160*e887ea33SDavid du Colombier 			indx(n);
161*e887ea33SDavid du Colombier 			l = new1(OINDEX, idx.basetree, idx.regtree);
162*e887ea33SDavid du Colombier 			l->scale = idx.scale;
163*e887ea33SDavid du Colombier 			l->addable = 9;
164*e887ea33SDavid du Colombier 			l->complex = l->right->complex;
165*e887ea33SDavid du Colombier 			l->type = l->left->type;
166*e887ea33SDavid du Colombier 			n->op = OADDR;
167*e887ea33SDavid du Colombier 			n->left = l;
168*e887ea33SDavid du Colombier 			n->right = Z;
169*e887ea33SDavid du Colombier 			n->addable = 8;
170*e887ea33SDavid du Colombier 			break;
171*e887ea33SDavid du Colombier 		}
172*e887ea33SDavid du Colombier 		break;
173*e887ea33SDavid du Colombier 
174*e887ea33SDavid du Colombier 	case OINDEX:
175*e887ea33SDavid du Colombier 		xcom(l);
176*e887ea33SDavid du Colombier 		xcom(r);
177*e887ea33SDavid du Colombier 		n->addable = 9;
178*e887ea33SDavid du Colombier 		break;
179*e887ea33SDavid du Colombier 
180*e887ea33SDavid du Colombier 	case OIND:
181*e887ea33SDavid du Colombier 		xcom(l);
182*e887ea33SDavid du Colombier 		if(l->op == OADDR) {
183*e887ea33SDavid du Colombier 			l = l->left;
184*e887ea33SDavid du Colombier 			l->type = n->type;
185*e887ea33SDavid du Colombier 			*n = *l;
186*e887ea33SDavid du Colombier 			return;
187*e887ea33SDavid du Colombier 		}
188*e887ea33SDavid du Colombier 		switch(l->addable) {
189*e887ea33SDavid du Colombier 		case 20:
190*e887ea33SDavid du Colombier 			n->addable = 21;
191*e887ea33SDavid du Colombier 			break;
192*e887ea33SDavid du Colombier 		case 1:
193*e887ea33SDavid du Colombier 			n->addable = 11;
194*e887ea33SDavid du Colombier 			break;
195*e887ea33SDavid du Colombier 		case 13:
196*e887ea33SDavid du Colombier 			n->addable = 10;
197*e887ea33SDavid du Colombier 			break;
198*e887ea33SDavid du Colombier 		}
199*e887ea33SDavid du Colombier 		break;
200*e887ea33SDavid du Colombier 
201*e887ea33SDavid du Colombier 	case OASHL:
202*e887ea33SDavid du Colombier 		xcom(l);
203*e887ea33SDavid du Colombier 		xcom(r);
204*e887ea33SDavid du Colombier 		indexshift(n);
205*e887ea33SDavid du Colombier 		break;
206*e887ea33SDavid du Colombier 
207*e887ea33SDavid du Colombier 	case OMUL:
208*e887ea33SDavid du Colombier 	case OLMUL:
209*e887ea33SDavid du Colombier 		xcom(l);
210*e887ea33SDavid du Colombier 		xcom(r);
211*e887ea33SDavid du Colombier 		g = vlog(l);
212*e887ea33SDavid du Colombier 		if(g >= 0) {
213*e887ea33SDavid du Colombier 			n->left = r;
214*e887ea33SDavid du Colombier 			n->right = l;
215*e887ea33SDavid du Colombier 			l = r;
216*e887ea33SDavid du Colombier 			r = n->right;
217*e887ea33SDavid du Colombier 		}
218*e887ea33SDavid du Colombier 		g = vlog(r);
219*e887ea33SDavid du Colombier 		if(g >= 0) {
220*e887ea33SDavid du Colombier 			n->op = OASHL;
221*e887ea33SDavid du Colombier 			r->vconst = g;
222*e887ea33SDavid du Colombier 			r->type = types[TINT];
223*e887ea33SDavid du Colombier 			indexshift(n);
224*e887ea33SDavid du Colombier 			break;
225*e887ea33SDavid du Colombier 		}
226*e887ea33SDavid du Colombier 		commute(n);
227*e887ea33SDavid du Colombier 		break;
228*e887ea33SDavid du Colombier 
229*e887ea33SDavid du Colombier 	case OASLDIV:
230*e887ea33SDavid du Colombier 		xcom(l);
231*e887ea33SDavid du Colombier 		xcom(r);
232*e887ea33SDavid du Colombier 		g = vlog(r);
233*e887ea33SDavid du Colombier 		if(g >= 0) {
234*e887ea33SDavid du Colombier 			n->op = OASLSHR;
235*e887ea33SDavid du Colombier 			r->vconst = g;
236*e887ea33SDavid du Colombier 			r->type = types[TINT];
237*e887ea33SDavid du Colombier 		}
238*e887ea33SDavid du Colombier 		break;
239*e887ea33SDavid du Colombier 
240*e887ea33SDavid du Colombier 	case OLDIV:
241*e887ea33SDavid du Colombier 		xcom(l);
242*e887ea33SDavid du Colombier 		xcom(r);
243*e887ea33SDavid du Colombier 		g = vlog(r);
244*e887ea33SDavid du Colombier 		if(g >= 0) {
245*e887ea33SDavid du Colombier 			n->op = OLSHR;
246*e887ea33SDavid du Colombier 			r->vconst = g;
247*e887ea33SDavid du Colombier 			r->type = types[TINT];
248*e887ea33SDavid du Colombier 			indexshift(n);
249*e887ea33SDavid du Colombier 			break;
250*e887ea33SDavid du Colombier 		}
251*e887ea33SDavid du Colombier 		break;
252*e887ea33SDavid du Colombier 
253*e887ea33SDavid du Colombier 	case OASLMOD:
254*e887ea33SDavid du Colombier 		xcom(l);
255*e887ea33SDavid du Colombier 		xcom(r);
256*e887ea33SDavid du Colombier 		g = vlog(r);
257*e887ea33SDavid du Colombier 		if(g >= 0) {
258*e887ea33SDavid du Colombier 			n->op = OASAND;
259*e887ea33SDavid du Colombier 			r->vconst--;
260*e887ea33SDavid du Colombier 		}
261*e887ea33SDavid du Colombier 		break;
262*e887ea33SDavid du Colombier 
263*e887ea33SDavid du Colombier 	case OLMOD:
264*e887ea33SDavid du Colombier 		xcom(l);
265*e887ea33SDavid du Colombier 		xcom(r);
266*e887ea33SDavid du Colombier 		g = vlog(r);
267*e887ea33SDavid du Colombier 		if(g >= 0) {
268*e887ea33SDavid du Colombier 			n->op = OAND;
269*e887ea33SDavid du Colombier 			r->vconst--;
270*e887ea33SDavid du Colombier 		}
271*e887ea33SDavid du Colombier 		break;
272*e887ea33SDavid du Colombier 
273*e887ea33SDavid du Colombier 	case OASMUL:
274*e887ea33SDavid du Colombier 	case OASLMUL:
275*e887ea33SDavid du Colombier 		xcom(l);
276*e887ea33SDavid du Colombier 		xcom(r);
277*e887ea33SDavid du Colombier 		g = vlog(r);
278*e887ea33SDavid du Colombier 		if(g >= 0) {
279*e887ea33SDavid du Colombier 			n->op = OASASHL;
280*e887ea33SDavid du Colombier 			r->vconst = g;
281*e887ea33SDavid du Colombier 		}
282*e887ea33SDavid du Colombier 		break;
283*e887ea33SDavid du Colombier 
284*e887ea33SDavid du Colombier 	case OLSHR:
285*e887ea33SDavid du Colombier 	case OASHR:
286*e887ea33SDavid du Colombier 		xcom(l);
287*e887ea33SDavid du Colombier 		xcom(r);
288*e887ea33SDavid du Colombier 		indexshift(n);
289*e887ea33SDavid du Colombier 		break;
290*e887ea33SDavid du Colombier 
291*e887ea33SDavid du Colombier 	default:
292*e887ea33SDavid du Colombier 		if(l != Z)
293*e887ea33SDavid du Colombier 			xcom(l);
294*e887ea33SDavid du Colombier 		if(r != Z)
295*e887ea33SDavid du Colombier 			xcom(r);
296*e887ea33SDavid du Colombier 		break;
297*e887ea33SDavid du Colombier 	}
298*e887ea33SDavid du Colombier brk:
299*e887ea33SDavid du Colombier 	if(n->addable >= 10)
300*e887ea33SDavid du Colombier 		return;
301*e887ea33SDavid du Colombier 	if(l != Z)
302*e887ea33SDavid du Colombier 		n->complex = l->complex;
303*e887ea33SDavid du Colombier 	if(r != Z) {
304*e887ea33SDavid du Colombier 		if(r->complex == n->complex)
305*e887ea33SDavid du Colombier 			n->complex = r->complex+1;
306*e887ea33SDavid du Colombier 		else
307*e887ea33SDavid du Colombier 		if(r->complex > n->complex)
308*e887ea33SDavid du Colombier 			n->complex = r->complex;
309*e887ea33SDavid du Colombier 	}
310*e887ea33SDavid du Colombier 	if(n->complex == 0)
311*e887ea33SDavid du Colombier 		n->complex++;
312*e887ea33SDavid du Colombier 
313*e887ea33SDavid du Colombier 	switch(n->op) {
314*e887ea33SDavid du Colombier 
315*e887ea33SDavid du Colombier 	case OFUNC:
316*e887ea33SDavid du Colombier 		n->complex = FNX;
317*e887ea33SDavid du Colombier 		break;
318*e887ea33SDavid du Colombier 
319*e887ea33SDavid du Colombier 	case OCAST:
320*e887ea33SDavid du Colombier 		if(l->type->etype == TUVLONG && typefd[n->type->etype])
321*e887ea33SDavid du Colombier 			n->complex += 2;
322*e887ea33SDavid du Colombier 		break;
323*e887ea33SDavid du Colombier 
324*e887ea33SDavid du Colombier 	case OLMOD:
325*e887ea33SDavid du Colombier 	case OMOD:
326*e887ea33SDavid du Colombier 	case OLMUL:
327*e887ea33SDavid du Colombier 	case OLDIV:
328*e887ea33SDavid du Colombier 	case OMUL:
329*e887ea33SDavid du Colombier 	case ODIV:
330*e887ea33SDavid du Colombier 	case OASLMUL:
331*e887ea33SDavid du Colombier 	case OASLDIV:
332*e887ea33SDavid du Colombier 	case OASLMOD:
333*e887ea33SDavid du Colombier 	case OASMUL:
334*e887ea33SDavid du Colombier 	case OASDIV:
335*e887ea33SDavid du Colombier 	case OASMOD:
336*e887ea33SDavid du Colombier 		if(r->complex >= l->complex) {
337*e887ea33SDavid du Colombier 			n->complex = l->complex + 3;
338*e887ea33SDavid du Colombier 			if(r->complex > n->complex)
339*e887ea33SDavid du Colombier 				n->complex = r->complex;
340*e887ea33SDavid du Colombier 		} else {
341*e887ea33SDavid du Colombier 			n->complex = r->complex + 3;
342*e887ea33SDavid du Colombier 			if(l->complex > n->complex)
343*e887ea33SDavid du Colombier 				n->complex = l->complex;
344*e887ea33SDavid du Colombier 		}
345*e887ea33SDavid du Colombier 		break;
346*e887ea33SDavid du Colombier 
347*e887ea33SDavid du Colombier 	case OLSHR:
348*e887ea33SDavid du Colombier 	case OASHL:
349*e887ea33SDavid du Colombier 	case OASHR:
350*e887ea33SDavid du Colombier 	case OASLSHR:
351*e887ea33SDavid du Colombier 	case OASASHL:
352*e887ea33SDavid du Colombier 	case OASASHR:
353*e887ea33SDavid du Colombier 		if(r->complex >= l->complex) {
354*e887ea33SDavid du Colombier 			n->complex = l->complex + 2;
355*e887ea33SDavid du Colombier 			if(r->complex > n->complex)
356*e887ea33SDavid du Colombier 				n->complex = r->complex;
357*e887ea33SDavid du Colombier 		} else {
358*e887ea33SDavid du Colombier 			n->complex = r->complex + 2;
359*e887ea33SDavid du Colombier 			if(l->complex > n->complex)
360*e887ea33SDavid du Colombier 				n->complex = l->complex;
361*e887ea33SDavid du Colombier 		}
362*e887ea33SDavid du Colombier 		break;
363*e887ea33SDavid du Colombier 
364*e887ea33SDavid du Colombier 	case OADD:
365*e887ea33SDavid du Colombier 	case OXOR:
366*e887ea33SDavid du Colombier 	case OAND:
367*e887ea33SDavid du Colombier 	case OOR:
368*e887ea33SDavid du Colombier 		/*
369*e887ea33SDavid du Colombier 		 * immediate operators, make const on right
370*e887ea33SDavid du Colombier 		 */
371*e887ea33SDavid du Colombier 		if(l->op == OCONST) {
372*e887ea33SDavid du Colombier 			n->left = r;
373*e887ea33SDavid du Colombier 			n->right = l;
374*e887ea33SDavid du Colombier 		}
375*e887ea33SDavid du Colombier 		break;
376*e887ea33SDavid du Colombier 
377*e887ea33SDavid du Colombier 	case OEQ:
378*e887ea33SDavid du Colombier 	case ONE:
379*e887ea33SDavid du Colombier 	case OLE:
380*e887ea33SDavid du Colombier 	case OLT:
381*e887ea33SDavid du Colombier 	case OGE:
382*e887ea33SDavid du Colombier 	case OGT:
383*e887ea33SDavid du Colombier 	case OHI:
384*e887ea33SDavid du Colombier 	case OHS:
385*e887ea33SDavid du Colombier 	case OLO:
386*e887ea33SDavid du Colombier 	case OLS:
387*e887ea33SDavid du Colombier 		/*
388*e887ea33SDavid du Colombier 		 * compare operators, make const on left
389*e887ea33SDavid du Colombier 		 */
390*e887ea33SDavid du Colombier 		if(r->op == OCONST) {
391*e887ea33SDavid du Colombier 			n->left = r;
392*e887ea33SDavid du Colombier 			n->right = l;
393*e887ea33SDavid du Colombier 			n->op = invrel[relindex(n->op)];
394*e887ea33SDavid du Colombier 		}
395*e887ea33SDavid du Colombier 		break;
396*e887ea33SDavid du Colombier 	}
397*e887ea33SDavid du Colombier }
398*e887ea33SDavid du Colombier 
399*e887ea33SDavid du Colombier void
indx(Node * n)400*e887ea33SDavid du Colombier indx(Node *n)
401*e887ea33SDavid du Colombier {
402*e887ea33SDavid du Colombier 	Node *l, *r;
403*e887ea33SDavid du Colombier 
404*e887ea33SDavid du Colombier 	if(debug['x'])
405*e887ea33SDavid du Colombier 		prtree(n, "indx");
406*e887ea33SDavid du Colombier 
407*e887ea33SDavid du Colombier 	l = n->left;
408*e887ea33SDavid du Colombier 	r = n->right;
409*e887ea33SDavid du Colombier 	if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) {
410*e887ea33SDavid du Colombier 		n->right = l;
411*e887ea33SDavid du Colombier 		n->left = r;
412*e887ea33SDavid du Colombier 		l = r;
413*e887ea33SDavid du Colombier 		r = n->right;
414*e887ea33SDavid du Colombier 	}
415*e887ea33SDavid du Colombier 	if(l->addable != 7) {
416*e887ea33SDavid du Colombier 		idx.regtree = l;
417*e887ea33SDavid du Colombier 		idx.scale = 1;
418*e887ea33SDavid du Colombier 	} else
419*e887ea33SDavid du Colombier 	if(l->right->addable == 20) {
420*e887ea33SDavid du Colombier 		idx.regtree = l->left;
421*e887ea33SDavid du Colombier 		idx.scale = 1 << l->right->vconst;
422*e887ea33SDavid du Colombier 	} else
423*e887ea33SDavid du Colombier 	if(l->left->addable == 20) {
424*e887ea33SDavid du Colombier 		idx.regtree = l->right;
425*e887ea33SDavid du Colombier 		idx.scale = 1 << l->left->vconst;
426*e887ea33SDavid du Colombier 	} else
427*e887ea33SDavid du Colombier 		diag(n, "bad index");
428*e887ea33SDavid du Colombier 
429*e887ea33SDavid du Colombier 	idx.basetree = r;
430*e887ea33SDavid du Colombier 	if(debug['x']) {
431*e887ea33SDavid du Colombier 		print("scale = %d\n", idx.scale);
432*e887ea33SDavid du Colombier 		prtree(idx.regtree, "index");
433*e887ea33SDavid du Colombier 		prtree(idx.basetree, "base");
434*e887ea33SDavid du Colombier 	}
435*e887ea33SDavid du Colombier }
436