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