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