1 #ifndef lint
2 static char *sccsid ="@(#)order.c 1.20 (Berkeley) 05/31/88";
3 #endif lint
4
5 # include "pass2.h"
6
7 int maxargs = { -1 };
8
9 /*ARGSUSED*/
stoasg(p,o)10 stoasg( p, o ) NODE *p; {
11 /* should the assignment op p be stored,
12 given that it lies as the right operand of o
13 (or the left, if o==UNARY MUL) */
14 }
15
deltest(p)16 deltest( p ) register NODE *p; {
17 /* should we delay the INCR or DECR operation p */
18 p = p->in.left;
19 return( p->in.op == REG || p->in.op == NAME || p->in.op == OREG );
20 }
21
autoincr(p)22 autoincr( p ) NODE *p; {
23 register NODE *q = p->in.left;
24 register TWORD t;
25
26 if( q->in.op != INCR ||
27 q->in.left->in.op != REG ||
28 !ISPTR(q->in.type) )
29 return(0);
30 t = q->in.type;
31 q->in.type = DECREF(t);
32 if( tlen(p) != tlen(q) ) { /* side effects okay? */
33 q->in.type = t;
34 return(0);
35 }
36 q->in.type = t;
37 if( tlen(p) != q->in.right->tn.lval )
38 return(0);
39
40 return(1);
41 }
42
mkadrs(p)43 mkadrs(p) register NODE *p; {
44 register int o;
45
46 o = p->in.op;
47
48 if( asgop(o) ){
49 if( p->in.left->in.su >= p->in.right->in.su ){
50 if( p->in.left->in.op == UNARY MUL ){
51 SETSTO( p->in.left->in.left, INTEMP );
52 }
53 else if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
54 SETSTO( p->in.left->in.left->in.left, INTEMP );
55 }
56 else { /* should be only structure assignment */
57 SETSTO( p->in.left, INTEMP );
58 }
59 }
60 else SETSTO( p->in.right, INTEMP );
61 }
62 else {
63 if( p->in.left->in.su > p->in.right->in.su ){
64 SETSTO( p->in.left, INTEMP );
65 }
66 else {
67 SETSTO( p->in.right, INTEMP );
68 }
69 }
70 }
71
72 /*ARGSUSED*/
notoff(t,r,off,cp)73 notoff( t, r, off, cp) TWORD t; CONSZ off; char *cp; {
74 /* is it legal to make an OREG or NAME entry which has an
75 /* offset of off, (from a register of r), if the
76 /* resulting thing had type t */
77
78 return(0); /* YES */
79 }
80
81 # define max(x,y) ((x)<(y)?(y):(x))
82
sucomp(p)83 sucomp( p ) register NODE *p; {
84
85 /* set the su field in the node to the sethi-ullman
86 number, or local equivalent */
87
88 register int o, ty, sul, sur, r;
89 int szr;
90 NODE *temp;
91
92 o = p->in.op;
93 ty = optype( o );
94 p->in.su = szty( p->in.type ); /* 2 for double, else 1 */;
95
96 if( ty == LTYPE ){
97 if( o == OREG ){
98 r = p->tn.rval;
99 /* oreg cost is (worst case) 1 + number of temp registers used */
100 if( R2TEST(r) ){
101 if( R2UPK1(r)!=100 && istreg(R2UPK1(r)) ) ++p->in.su;
102 if( istreg(R2UPK2(r)) ) ++p->in.su;
103 }
104 else {
105 if( istreg( r ) ) ++p->in.su;
106 }
107 }
108 if( p->in.su == szty(p->in.type) &&
109 (p->in.op!=REG || !istreg(p->tn.rval)) &&
110 (p->in.type==INT ||
111 p->in.type==UNSIGNED ||
112 #if defined(FORT) || defined(SPRECC)
113 p->in.type==FLOAT ||
114 #endif
115 p->in.type==DOUBLE ||
116 ISPTR(p->in.type) ||
117 ISARY(p->in.type)) )
118 p->in.su = 0;
119 return;
120 }
121
122 else if( ty == UTYPE ){
123 switch( o ) {
124 case UNARY CALL:
125 case UNARY STCALL:
126 p->in.su = fregs; /* all regs needed */
127 return;
128
129 default:
130 p->in.su = p->in.left->in.su + (szty( p->in.type ) > 1 ? 2 : 0) ;
131 return;
132 }
133 }
134
135
136 /* If rhs needs n, lhs needs m, regular su computation */
137
138 sul = p->in.left->in.su;
139 sur = p->in.right->in.su;
140 szr = szty( p->in.right->in.type );
141 if( szty( p->in.type ) > szr && szr >= 1 ) {
142 /* implicit conversion in rhs */
143 szr = szty( p->in.type );
144 sur = max( szr, sur );
145 }
146
147 if( o == ASSIGN ){
148 /* computed by doing right, then left (if not in mem), then doing it */
149 p->in.su = max(sur,sul+1);
150 return;
151 }
152
153 if( o == CALL || o == STCALL ){
154 /* in effect, takes all free registers */
155 p->in.su = fregs;
156 return;
157 }
158
159 if( o == STASG ){
160 /* right, then left */
161 p->in.su = max( max( 1+sul, sur), fregs );
162 return;
163 }
164
165 switch( o ){
166 case DIV:
167 case ASG DIV:
168 case MOD:
169 case ASG MOD:
170 /* EDIV instructions require reg pairs */
171 if( p->in.left->in.type == UNSIGNED &&
172 p->in.right->in.op == ICON &&
173 p->in.right->tn.name[0] == '\0' &&
174 (unsigned) p->in.right->tn.lval < 0x80000000 ) {
175 p->in.su = sul + 2;
176 return;
177 }
178 break;
179 }
180
181 if( asgop(o) ){
182 /* computed by doing right, doing left address, doing left, op, and store */
183 p->in.su = max(sur,sul+2);
184 return;
185 }
186
187 switch( o ){
188 case ANDAND:
189 case OROR:
190 case QUEST:
191 case COLON:
192 case COMOP:
193 p->in.su = max( max(sul,sur), 1);
194 return;
195
196 case PLUS:
197 case MUL:
198 case OR:
199 case ER:
200 /* commutative ops; put harder on left */
201 if( p->in.right->in.su > p->in.left->in.su && !istnode(p->in.left) ){
202 temp = p->in.left;
203 p->in.left = p->in.right;
204 p->in.right = temp;
205 sul = p->in.left->in.su;
206 sur = p->in.right->in.su;
207 szr = szty( p->in.right->in.type );
208 if( szty( p->in.type ) > szr && szr >= 1 ) {
209 /* implicit conversion in rhs */
210 szr = szty( p->in.type );
211 sur = max( szr, sur );
212 }
213 }
214 break;
215 }
216 /* binary op, computed by left, then right, then do op */
217 p->in.su = max(sul,szr+sur);
218
219 }
220
221 int radebug = 0;
222
rallo(p,down)223 rallo( p, down ) NODE *p; {
224 /* do register allocation */
225 register int o, down1, down2, ty;
226
227 if( radebug ) printf( "rallo( %o, %d )\n", p, down );
228
229 down2 = NOPREF;
230 p->in.rall = down;
231 down1 = ( down &= ~MUSTDO );
232
233 ty = optype( o = p->in.op );
234 switch( o ) {
235 case ASSIGN:
236 down1 = NOPREF;
237 down2 = down;
238 break;
239
240 case CALL:
241 case STASG:
242 case EQ:
243 case NE:
244 case GT:
245 case GE:
246 case LT:
247 case LE:
248 case NOT:
249 case ANDAND:
250 case OROR:
251 down1 = NOPREF;
252 break;
253
254 case FORCE:
255 down1 = R0|MUSTDO;
256 break;
257
258 }
259
260 if( ty != LTYPE ) rallo( p->in.left, down1 );
261 if( ty == BITYPE ) rallo( p->in.right, down2 );
262
263 }
264
offstar(p)265 offstar( p ) register NODE *p; {
266 if( p->in.op == PLUS ) {
267 /* try to create index expressions */
268 if( p->in.left->in.op==LS &&
269 p->in.left->in.left->in.op!=REG &&
270 p->in.left->in.right->in.op==ICON &&
271 p->in.left->in.right->tn.lval<=3 ){
272 order( p->in.left->in.left, INTAREG|INAREG );
273 return;
274 }
275 if( p->in.left->in.su == fregs ) {
276 order( p->in.left, INTAREG|INAREG );
277 return;
278 }
279 if( p->in.right->in.op==LS &&
280 p->in.right->in.left->in.op!=REG &&
281 p->in.right->in.right->in.op==ICON &&
282 p->in.right->in.right->tn.lval<=3 ){
283 order( p->in.right->in.left, INTAREG|INAREG );
284 return;
285 }
286 if( p->in.right->in.su == fregs ) {
287 order( p->in.right, INTAREG|INAREG );
288 return;
289 }
290 if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) {
291 if( (p->in.left->in.op == ICON ||
292 p->in.left->in.op == NAME) &&
293 p->in.right->in.op != REG ) {
294 order(p->in.right, INTAREG|INAREG);
295 return;
296 }
297 if( p->in.left->in.op!=REG ) {
298 order( p->in.left, INTAREG|INAREG );
299 return;
300 }
301 if( p->in.right->in.op!=REG ) {
302 order(p->in.right, INTAREG|INAREG);
303 return;
304 }
305 }
306 }
307 if( p->in.op == PLUS || p->in.op == MINUS ){
308 if( p->in.right->in.op == ICON ){
309 p = p->in.left;
310 order( p , INTAREG|INAREG);
311 return;
312 }
313 }
314
315 if( p->in.op == UNARY MUL && !canaddr(p) ) {
316 offstar( p->in.left );
317 return;
318 }
319
320 order( p, INTAREG|INAREG );
321 }
322
setincr(p)323 setincr( p ) register NODE *p; {
324 p = p->in.left;
325 if( p->in.op == UNARY MUL ){
326 offstar( p->in.left );
327 return( 1 );
328 }
329 return( 0 );
330 }
331
setbin(p)332 setbin( p ) register NODE *p; {
333 register int ro, rt;
334
335 rt = p->in.right->in.type;
336 ro = p->in.right->in.op;
337
338 if( canaddr( p->in.left ) && !canaddr( p->in.right ) ) { /* address rhs */
339 if( ro == UNARY MUL ) {
340 offstar( p->in.right->in.left );
341 return(1);
342 } else {
343 order( p->in.right, INAREG|INTAREG|SOREG );
344 return(1);
345 }
346 }
347 if( !istnode( p->in.left) ) { /* try putting LHS into a reg */
348 order( p->in.left, INAREG|INTAREG|INBREG|INTBREG|SOREG );
349 return(1);
350 }
351 else if( ro == UNARY MUL && rt != CHAR && rt != UCHAR ){
352 offstar( p->in.right->in.left );
353 return(1);
354 }
355 else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT ||
356 #ifndef SPRECC
357 rt == FLOAT ||
358 #endif
359 (ro != REG && ro != NAME && ro != OREG && ro != ICON ) ){
360 order( p->in.right, INAREG|INBREG );
361 return(1);
362 }
363 return(0);
364 }
365
setstr(p)366 setstr( p ) register NODE *p; { /* structure assignment */
367 if( p->in.right->in.op != REG ){
368 order( p->in.right, INTAREG );
369 return(1);
370 }
371 p = p->in.left;
372 if( p->in.op != NAME && p->in.op != OREG ){
373 if( p->in.op != UNARY MUL ) cerror( "bad setstr" );
374 order( p->in.left, INTAREG );
375 return( 1 );
376 }
377 return( 0 );
378 }
379
setasg(p)380 setasg( p ) register NODE *p; {
381 /* setup for assignment operator */
382
383 if( !canaddr(p->in.right) ) {
384 if( p->in.right->in.op == UNARY MUL )
385 offstar(p->in.right->in.left);
386 else
387 order( p->in.right, INAREG|INBREG|SOREG );
388 return(1);
389 }
390 if( p->in.left->in.op == UNARY MUL ) {
391 offstar( p->in.left->in.left );
392 return(1);
393 }
394 if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
395 offstar( p->in.left->in.left->in.left );
396 return(1);
397 }
398 /* FLD patch */
399 if( p->in.left->in.op == FLD && !(p->in.right->in.type==INT || p->in.right->in.type==UNSIGNED)) {
400 order( p->in.right, INAREG);
401 return(1);
402 }
403 /* end of FLD patch */
404 return(0);
405 }
406
setasop(p)407 setasop( p ) register NODE *p; {
408 /* setup for =ops */
409 register int rt, ro;
410
411 rt = p->in.right->in.type;
412 ro = p->in.right->in.op;
413
414 if( ro == UNARY MUL && rt != CHAR ){
415 offstar( p->in.right->in.left );
416 return(1);
417 }
418 if( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT ||
419 #ifndef SPRECC
420 rt == FLOAT ||
421 #endif
422 ( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ){
423 order( p->in.right, INAREG|INBREG );
424 return(1);
425 }
426
427
428 p = p->in.left;
429 if( p->in.op == FLD ) p = p->in.left;
430
431 switch( p->in.op ){
432
433 case REG:
434 case ICON:
435 case NAME:
436 case OREG:
437 return(0);
438
439 case UNARY MUL:
440 if( p->in.left->in.op==OREG )
441 return(0);
442 else
443 offstar( p->in.left );
444 return(1);
445
446 }
447 cerror( "illegal setasop" );
448 /*NOTREACHED*/
449 }
450
451 int crslab = 99999; /* VAX */
452
getlab()453 getlab(){
454 return( crslab-- );
455 }
456
deflab(l)457 deflab( l ){
458 if (nerrors) return;
459 printf( "L%d:\n", l );
460 }
461
genargs(p)462 genargs( p ) register NODE *p; {
463 register NODE *pasg;
464 register int align;
465 register int size;
466 int count;
467
468 /* generate code for the arguments */
469
470 /* first, do the arguments on the right */
471 while( p->in.op == CM ){
472 genargs( p->in.right );
473 p->in.op = FREE;
474 p = p->in.left;
475 }
476
477 if( p->in.op == STARG ){ /* structure valued argument */
478
479 size = p->stn.stsize;
480 align = p->stn.stalign;
481 if( p->in.left->in.op == ICON ){
482 p->in.op = FREE;
483 p = p->in.left;
484 }
485 else {
486 /* make it look beautiful... */
487 p->in.op = UNARY MUL;
488 canon( p ); /* turn it into an oreg */
489 for( count = 0; p->in.op != OREG && count < 10; ++count ){
490 offstar( p->in.left );
491 canon( p );
492 }
493 if( p->in.op != OREG ) cerror( "stuck starg" );
494 }
495
496 pasg = talloc();
497 pasg->in.op = STARG;
498 pasg->in.rall = NOPREF;
499 pasg->stn.stsize = size;
500 pasg->stn.stalign = align;
501 pasg->in.left = p;
502
503 order( pasg, FORARG );
504 return;
505 }
506
507 /* ordinary case */
508
509 order( p, FORARG );
510 }
511
argsize(p)512 argsize( p ) register NODE *p; {
513 register int t;
514 t = 0;
515 if( p->in.op == CM ){
516 t = argsize( p->in.left );
517 p = p->in.right;
518 }
519 if( p->in.type == DOUBLE || p->in.type == FLOAT ){
520 SETOFF( t, 4 );
521 return( t+8 );
522 }
523 else if( p->in.op == STARG ){
524 SETOFF( t, 4 ); /* alignment */
525 return( t + ((p->stn.stsize+3)/4)*4 ); /* size */
526 }
527 else {
528 SETOFF( t, 4 );
529 return( t+4 );
530 }
531 }
532