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