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