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