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