|
|
1.1 root 1: #ifndef lint
2: static char *sccsid ="@(#)order.c 1.20 (Berkeley) 5/31/88";
3: #endif lint
4:
5: # include "pass2.h"
6:
7: int maxargs = { -1 };
8:
9: /*ARGSUSED*/
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:
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:
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:
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*/
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:
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:
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:
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:
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:
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:
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:
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:
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:
453: getlab(){
454: return( crslab-- );
455: }
456:
457: deflab( l ){
458: if (nerrors) return;
459: printf( "L%d:\n", l );
460: }
461:
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:
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.