|
|
1.1 root 1: # include "mfile2"
2:
3: int maxargs = { -1 };
4:
5: stoasg( 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:
15: deltest( 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:
21: autoincr( 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:
31: mkadrs(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:
60: notoff( 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:
71: sucomp( 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:
177: int radebug = 0;
178:
179: rallo( 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:
250: offstar( 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:
296: setincr( p ) NODE *p; {
297: return( 0 ); /* for the moment, don't bother */
298: }
299:
300: setbin( 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:
339: setstr( 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:
353: setasg( 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:
380: setasop( 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:
426: int crslab = 9999; /* Honeywell */
427:
428: getlab(){
429: return( crslab-- );
430: }
431:
432: deflab( l ){
433: printf( "L%d:\n", l );
434: }
435:
436: genargs( 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:
500: argsize( 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.