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