|
|
1.1 root 1: /* @(#) reader.c : 1.7 3/5/84 */
2:
3: # include "mfile2.h"
4:
5: /* some storage declarations */
6:
7: # ifdef TWOPASS
8: NODE node[TREESZ];
9: char ftitle[100] = "\"\""; /* the name of the file */
10: int ftnno; /* number of current function */
11: int lineno;
12: #endif
13:
14: int lflag;
15: int e2debug;
16: int udebug;
17: int fast;
18:
19: /* maxtemp is the maximum size (in bits) needed for temps so far */
20: /* maxarg is ditto for outgoing arguments */
21: /* maxboff is ditto for automatic variables */
22: /* earlier attempts to keep these on a per-block basis were silly */
23: int maxtemp;
24: extern int maxarg;
25: int maxboff;
26: NODE * condit();
27:
28: NODE *
29: force(p)
30: register NODE *p;
31: {
32: register NODE *q, *r;
33: if( !p ) cerror( "force" );
34: q = talloc();
35: *q = *p;
36: r = talloc();
37: *r = *p;
38: q->tn.op = ASSIGN;
39: q->in.right = p;
40: q->in.left = r;
41: r->tn.op = QNODE;
42: r->tn.rval = callreg(p); /* the reg where the value will be forced */
43: return( q );
44: }
45:
46: p2init( argc, argv )
47: char *argv[];
48: {
49: /* set the values of the pass 2 arguments */
50:
51: register int c;
52: register char *cp;
53: register files;
54:
55: allo0(); /* free all regs */
56: files = 0;
57:
58: for( c=1; c<argc; ++c )
59: {
60: if( *(cp=argv[c]) == '-' )
61: {
62: while( *++cp )
63: {
64: switch( *cp )
65: {
66:
67: case 'X': /* pass1 flags */
68: while( *++cp )
69: {
70: /* VOID */
71: }
72: --cp;
73: break;
74:
75: case 'l': /* linenos */
76: ++lflag;
77: break;
78:
79: case 'e': /* expressions */
80: ++e2debug;
81: break;
82:
83: case 'o': /* orders */
84: ++odebug;
85: break;
86:
87: case 'r': /* register allocation */
88: ++rdebug;
89: break;
90:
91: case 's': /* shapes */
92: ++sdebug;
93: break;
94:
95: case 'u': /* Sethi-Ullman testing
96: (machine dependent) */
97: ++udebug;
98: break;
99:
100: case 'f': /* try for faster compile speed */
101: ++fast;
102: break;
103:
104: default:
105: cerror( "bad option: %c", *cp );
106: }
107: }
108: }
109: else files = 1; /* assumed to be a ftitle */
110: }
111:
112: mkdope();
113: return( files );
114: }
115:
116: NODE *
117: dlabel( p, l )
118: register NODE *p;
119: {
120: /* define a label after p is executed */
121: register NODE *q;
122: if( !p ) cerror( "dlabel" );
123: q = talloc();
124: q->tn.type = p->tn.type;
125: q->in.left = p;
126: q->tn.op = GENLAB;
127: q->bn.label = l;
128: return( q );
129: }
130:
131:
132: NODE *
133: genbr( o, l, p )
134: register NODE *p;
135: register o,l;
136: {
137: /* after evaluating p, generate a branch to l */
138: /* if o is 0, unconditional */
139: register NODE *q;
140: if( !p ) cerror( "genbr" );
141: if( l < 0 ) cerror( "genbr1" );
142: q = talloc();
143: q->tn.op = o?GENBR:GENUBR;
144: q->tn.type = p->tn.type;
145: q->in.left = p;
146: q->bn.label = l;
147: q->bn.lop = o;
148: if( o && logop(p->tn.op) &&
149: (p->tn.op != ANDAND)
150: && (p->tn.op != OROR)
151: ) p->tn.op = CMP;
152: return( q );
153: }
154:
155:
156: static NODE *
157: oreff(p)
158: register NODE *p;
159: {
160: register NODE *r, *l;
161: NODE *condit(), *seq();
162: int lab, t, f;
163: /* oreff is called if an || op is evaluated with goal=CEFF
164: The rhs of || ops should be executed only if the
165: lhs is false. Since our goal is CEFF, we don't need
166: a result of the ||, but we need to
167: preserve that dependancy with this special case */
168:
169: /* We must catch this case before its children are
170: condit() and change the goal on it left child to CCC */
171:
172: if (tcond(p->in.left)) {
173: tfree(p->in.right);
174: p->in.op = FREE;
175: p = condit( p->in.left, CEFF, -1, -1);
176: } else if (fcond(p->in.left)) {
177: p->in.op = COMOP;
178: p = condit( p, CEFF, -1, -1);
179: } else {
180: lab = getlab();
181: l = condit( p->in.left, CCC, lab, -1);
182: r = condit( p->in.right, CEFF, -1, -1);
183: p->in.op = FREE;
184: p = seq(l, r); /* put r after l */
185: p = dlabel(p, lab);
186: }
187: return p;
188: }
189: static NODE *
190: andeff(p)
191: register NODE *p;
192: {
193: register NODE *r, *l;
194: NODE *condit();
195: int lab, t, f;
196: /* andeff is called if an && op is evaluated with goal=CEFF
197: The rhs of && ops should be executed only if the
198: lhs is true. Since our goal is CEFF, we don't need
199: a result of the &&, but we need to
200: preserve that dependancy with this special case */
201:
202: /* We must catch this case before its children are
203: condit() and change the goal on it left child to CCC */
204:
205: if (fcond(p->in.left)) {
206: tfree(p->in.right);
207: p->in.op = FREE;
208: p = condit( p->in.left, CEFF, -1, -1);
209: } else if (tcond(p->in.left)) {
210: p->in.op = COMOP;
211: p = condit( p, CEFF, -1, -1);
212: } else {
213: lab = getlab();
214: p->in.op = FREE;
215: l = condit( p->in.left, CCC, -1, lab);
216: r = condit( p->in.right, CEFF, -1, -1);
217: p = seq(l, r); /* put r after l */
218: p = dlabel(p, lab);
219: }
220: return p;
221: }
222: int negrel[] =
223: {
224: NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE
225: } ; /* negatives of relationals */
226:
227: tcond( p )
228: register NODE *p;
229: {
230: /* return 1 if p is always true, 0 otherwise */
231: register o = p->tn.op;
232: register NODE *q;
233:
234: switch( o )
235: {
236:
237: case ICON:
238: return( p->tn.lval || p->tn.name != (char *) 0 );
239:
240: case COMOP:
241: return( tcond( p->in.right ) );
242:
243: case ANDAND:
244: return( tcond( p->in.left ) && tcond( p->in.right ) );
245:
246: case OROR:
247: return( tcond( p->in.left ) || tcond( p->in.right ) );
248:
249: case NOT:
250: return( fcond( p->in.left ) );
251:
252: case QUEST:
253: q = p->in.right;
254: if( tcond( p->in.left ) ) return( tcond( q->in.left ) );
255: if( fcond( p->in.left ) ) return( tcond( q->in.right ) );
256: return( tcond( q->in.left ) && tcond( q->in.right ) );
257:
258: default:
259: return( 0 );
260: }
261: }
262:
263: fcond( p )
264: register NODE *p;
265: {
266: /* return 1 if p is always false, 0 otherwise */
267: register o = p->tn.op;
268: register NODE *q;
269:
270: switch( o )
271: {
272:
273: case ICON:
274: return( !p->tn.lval && p->tn.name == (char *) 0 );
275:
276: case COMOP:
277: return( fcond( p->in.right ) );
278:
279: case ANDAND:
280: return( fcond( p->in.left ) || fcond( p->in.right ) );
281:
282: case OROR:
283: return( fcond( p->in.left ) && fcond( p->in.right ) );
284:
285: case NOT:
286: return( tcond( p->in.left ) );
287:
288: case QUEST:
289: q = p->in.right;
290: if( tcond( p->in.left ) ) return( fcond( q->in.left ) );
291: if( fcond( p->in.left ) ) return( fcond( q->in.right ) );
292: return( fcond( q->in.left ) && fcond( q->in.right ) );
293:
294: default:
295: return( 0 );
296: }
297: }
298:
299: NODE *
300: rcomma( p )
301: register NODE *p;
302: {
303: /* p is a COMOP; return the shrunken version thereof */
304:
305: if( p->tn.op != COMOP ) cerror( "rcomma" );
306:
307: if( p->in.left && p->in.right ) return( p );
308: p->tn.op = FREE;
309: if( !p->in.left ) return( p->in.right );
310: return( p->in.left );
311: }
312:
313: NODE *
314: seq( p1, p2 )
315: register NODE *p1, *p2;
316: {
317: /* execute p then q */
318: register NODE *q;
319:
320: q = talloc();
321: if (!p1) return p2;
322: if (!p2) return p1;
323: q->in.op = COMOP;
324: q->in.type = p2->in.right->in.type;
325: q->in.left = p1;
326: q->in.right = p2;
327: return q;
328: }
329:
330: NODE *
331: gtb( p, l )
332: register NODE *p;
333: register l;
334: {
335: register NODE *q;
336: /* replace p by a trivial branch to l */
337: /* if l is -1, return NULL */
338: q = condit( p, CEFF, -1, -1 );
339: if( l<0 ) return( q );
340: if( !q )
341: {
342: q = talloc();
343: q->tn.op = ICON;
344: q->tn.lval = 0;
345: q->tn.name = (char *) 0;
346: q->tn.type = TINT;
347: }
348: return( genbr( 0, l, q ) );
349: }
350:
351: NODE *
352: condit( p, goal, t, f )
353: register NODE *p;
354: register goal,t,f;
355: {
356: /* generate code for conditionals in terms of GENLAB and GENBR nodes */
357: /* goal is either CEFF, NRGS, or CCC */
358: /* also, delete stuff that never needs get done */
359: /* if goal==CEFF, return of null means nothing to be done */
360:
361: register o, lt, lf, l;
362: register NODE *q, *q1, *q2;
363:
364: o = p->tn.op;
365:
366: #ifndef NODBG
367: if( odebug >2 )
368: {
369: printf( "condit( %d (%s), %s, %d, %d )\n", (int)(p-node),
370: opst[o], goal==CCC?"CCC":(goal==NRGS?"NRGS":"CEFF"),
371: t, f );
372: }
373: #endif
374: if( o == CBRANCH )
375: {
376: p->in.right->tn.op = p->tn.op = FREE;
377: l = p->in.right->tn.lval;
378: p = p->in.left;
379: if( fcond( p ) ) return( gtb(p,l) );
380: if( tcond( p ) ) return( gtb(p,-1) );
381: return( condit( p, CCC, -1, l ) );
382: }
383:
384: /* a convenient place to diddle a few special ops */
385: if( callop(o) )
386: {
387: if( optype(o) == UTYPE ) p->stn.argsize = 0;
388: else p->stn.argsize = argsize(p->in.right);
389: if( goal==CEFF ) goal = NRGS;
390: /* flow on, so that we can handle if( f(...) )... */
391: }
392: else if( goal==CEFF && (asgop(o) || o==STASG || o==INIT)) goal=NRGS;
393:
394: /* do a bit of optimization */
395:
396: if( goal == NRGS )
397: {
398: if( logop(o) )
399: {
400: /* must make p into ( p ? 1 : 0 ), then recompile */
401: q1 = talloc();
402: q1->tn.op = ICON;
403: q1->tn.name = (char *) 0;
404: q1->tn.lval = 1;
405: q1->tn.type = p->tn.type;
406: q2 = talloc();
407: *q2 = *q1;
408: q2->tn.lval = 0;
409: q = talloc();
410: q->tn.op = COLON;
411: q->tn.type = p->tn.type;
412: q->in.left = q1;
413: q->in.right = q2;
414: q1 = talloc();
415: q1->tn.op = o = QUEST;
416: q1->tn.type = p->tn.type;
417: q1->in.left = p;
418: q1->in.right = q;
419: p = q1; /* flow on, and compile */
420: }
421: }
422:
423: if( goal != CCC )
424: {
425: if( o == QUEST )
426: {
427: /* rewrite ? : when goal not CCC */
428: lf = getlab();
429: l = getlab();
430: p->tn.op = COMOP;
431: q = p->in.right;
432: q1 = condit( q->in.left, goal, -1, -1 );
433: q->in.right = condit( q->in.right, goal, -1, -1 );
434: if( tcond( p->in.left ) )
435: {
436: q->tn.op = FREE;
437: tfree( q->in.right );
438: p->in.right = q1;
439: p->in.left=condit( p->in.left, CEFF, -1, -1 );
440: return( rcomma( p ) );
441: }
442: if( fcond( p->in.left ) )
443: {
444: q->tn.op = FREE;
445: tfree( q1 );
446: p->in.right = q->in.right;
447: p->in.left=condit( p->in.left, CEFF, -1, -1 );
448: return( rcomma( p ) );
449: }
450: if( !q1 )
451: {
452: if( !q->in.right )
453: {
454: /* may still have work to do
455: ** if left side of ? has effect
456: */
457: q1 = condit(p->in.left, goal,
458: -1, -1);
459: if (!q1)
460: {
461: tfree( p->in.left );
462: }
463: p->tn.op = q->tn.op = FREE;
464: return( q1 );
465: }
466: /* rhs done if condition is false */
467: p->in.left = condit( p->in.left, CCC, l, -1 );
468: p->in.right = dlabel( q->in.right, l );
469: q->tn.op = FREE;
470: return( p );
471: }
472: else if( !q->in.right )
473: {
474: /* lhs done if condition is true */
475: p->in.left=condit( p->in.left, CCC, -1, lf );
476: p->in.right = dlabel( q1, lf );
477: q->tn.op = FREE;
478: return( p );
479: }
480:
481: /* both sides exist and the condition is nontrivial */
482: p->in.left = condit( p->in.left, CCC, -1, lf );
483: q1 = force(q1);
484: q->in.right = force(q->in.right);
485: q1 = genbr( 0, l, q1 );
486: q->in.left = dlabel( q1, lf );
487: q->tn.op = COMOP;
488: return( dlabel( p, l ) );
489: }
490:
491: if( goal == CEFF )
492: {
493: /* some things may disappear */
494: switch( o )
495: {
496:
497: case CBRANCH:
498: case GENBR:
499: case GENUBR:
500: case CALL:
501: case UNARY CALL:
502: case FORTCALL:
503: case UNARY FORTCALL:
504: case STCALL:
505: case UNARY STCALL:
506: case STASG:
507: case INIT:
508: case MOD: /* do these for the side effects */
509: case DIV:
510: case UOP0:
511: case UOP1:
512: case UOP2:
513: case UOP3:
514: case UOP4:
515: case UOP5:
516: case UOP6:
517: case UOP7:
518: case UOP8:
519: case UOP9:
520: goal = NRGS;
521: }
522: }
523:
524: /* The rhs of && and || ops are executed only if the
525: result is not clear from the lhs. If our goal is
526: CEFF, we don't need a result, but we need to
527: preserve that dependancy. So special case it. */
528: if (goal==CEFF) {
529: if (o == ANDAND) return andeff(p);
530: if (o == OROR) return oreff(p);
531: }
532: /* This next batch of code wanders over the tree getting
533: rid of code which is for effect only and has no
534: effect */
535: switch( optype(o) )
536: {
537: case LTYPE:
538: if( goal == CEFF )
539: {
540: p->tn.op = FREE;
541: return( NIL );
542: }
543: break;
544:
545: case BITYPE:
546: p->in.right = condit( p->in.right, goal, -1, -1 );
547: case UTYPE:
548: p->in.left = condit( p->in.left, o==COMOP?CEFF:goal,
549: -1, -1 );
550: }
551: /* If we are only interested in effects, we quit here */
552: if( goal == CEFF || o==COMOP )
553: {
554: /* lhs or rhs may have disappeared */
555: /* op need not get done */
556:
557: switch( optype(o) )
558: {
559:
560: case BITYPE:
561: p->tn.op = COMOP;
562: p = rcomma(p);
563: return ( p );
564:
565: case UTYPE:
566: p->tn.op = FREE;
567: return( p->in.left );
568:
569: case LTYPE:
570: p->tn.op = FREE;
571: return( NIL );
572: }
573: }
574: return( p );
575: }
576:
577: /* goal must = CCC from here on */
578:
579: switch( o )
580: {
581:
582: case ULE:
583: case ULT:
584: case UGE:
585: case UGT:
586: case EQ:
587: case NE:
588: case LE:
589: case LT:
590: case GE:
591: case GT:
592: if(t<0 )
593: {
594: o = p->tn.op = negrel[o-EQ];
595: t = f;
596: f = -1;
597: }
598:
599: #ifndef NOOPT
600: if( p->in.right->in.op == ICON &&
601: p->in.right->tn.lval == 0 &&
602: p->in.right->in.name == (char *) 0 )
603: {
604: /* if chars are unsigned, do these optimizations
605: as if this is an unsigned compare*/
606: #ifndef CHSIGN
607: if (
608: ( p->in.left->tn.type == TCHAR ||
609: ( p->in.left->in.op == CONV &&
610: p->in.left->in.left->tn.type == TCHAR ) )
611: && o >= LE && o <= GT)
612: o += UGT - GT;
613: #endif
614:
615: /* the question here is whether we can assume that */
616: /* unconditional branches preserve condition codes */
617: /* if this turned out to be no, we would have to */
618: /* explicitly handle this case here */
619:
620: switch( o )
621: {
622:
623: case UGT:
624: case ULE:
625: o = p->in.op = (o==UGT)?NE:EQ;
626: case EQ:
627: case NE:
628: case LE:
629: case LT:
630: case GE:
631: case GT:
632: if( logop( p->in.left->tn.op ) )
633: {
634: /* situation like (a==0)==0 */
635: /* ignore optimization */
636: goto noopt;
637: }
638: break;
639:
640: case ULT: /* never succeeds */
641: return( gtb( p, f ) );
642:
643: case UGE:
644: /* always succeeds */
645: return( gtb( p, t ) );
646: }
647: p->tn.op = p->in.right->tn.op = FREE;
648: p = condit( p->in.left, NRGS, -1, -1 );
649: p = genbr( o, t, p );
650: if( f<0 ) return( p );
651: else return( genbr( 0, f, p ) );
652: }
653: noopt:
654: # endif
655:
656: p->in.left = condit( p->in.left, NRGS, -1, -1 );
657: p->in.right = condit( p->in.right, NRGS, -1, -1 );
658: p = genbr( o, t, p );
659: if( f>=0 ) p = genbr( 0, f, p );
660: return( p );
661:
662: case COMOP:
663: p->in.left = condit( p->in.left, CEFF, -1, -1 );
664: p->in.right = condit( p->in.right, CCC, t, f );
665: return( rcomma( p ) );
666:
667: case NOT:
668: p->tn.op = FREE;
669: return( condit( p->in.left, CCC, f, t ) );
670:
671: case ANDAND:
672: lf = f<0 ? getlab() : f;
673: lt = t<0 ? getlab() : t;
674: p->tn.op = COMOP;
675: if( tcond( p->in.left ) )
676: {
677: /* left is always true */
678: p->in.left = condit( p->in.left, CEFF, -1, -1 );
679: p->in.right = condit( p->in.right, CCC, t, f );
680: }
681: else {
682: /* lhs not always true */
683: if( tcond( p->in.right ) )
684: {
685: /* rhs is always true */
686: p->in.right =
687: condit( p->in.right, CEFF, -1, -1 );
688: if (p->in.right) {
689: /* const with sideeffect */
690: p->in.left =
691: condit( p->in.left, CCC, -1,lf);
692: p->in.right = condit( p->in.right,
693: CCC, t, t );
694: } else
695: p->in.left =
696: condit( p->in.left, CCC, t, f );
697: } else {
698: p->in.left =
699: condit( p->in.left, CCC, -1, lf );
700: p->in.right =
701: condit( p->in.right, CCC, t, f );
702: }
703: }
704: q = rcomma( p );
705: if( f<0 ) q = dlabel( q, lf );
706: if( t<0 ) q = dlabel( q, lt );
707: return( q );
708:
709: case OROR:
710: lf = f<0 ? getlab() : f;
711: lt = t<0 ? getlab() : t;
712: p->tn.op = COMOP;
713: if( fcond( p->in.left ) )
714: {
715: /* left is always false */
716: p->in.left = condit( p->in.left, CEFF, -1, -1 );
717: p->in.right = condit( p->in.right, CCC, t, f );
718: }
719: else {
720: /* left is not always false */
721: if( fcond( p->in.right ) )
722: {
723: /* right always false */
724: p->in.right =
725: condit( p->in.right, CEFF, -1, -1 );
726: if (p->in.right) {
727: /* const with sideeffect */
728: p->in.left =
729: condit( p->in.left, CCC, lt,-1);
730: /* This may generate a superfluous
731: test. Tough. */
732: p->in.right = condit( p->in.right,
733: CCC, f, f );
734: } else
735: p->in.left =
736: condit( p->in.left, CCC, t, f );
737: } else {
738: p->in.left =
739: condit( p->in.left, CCC, lt, -1 );
740: p->in.right =
741: condit( p->in.right, CCC, t, f );
742: }
743: }
744: p = rcomma( p );
745: if( f<0 ) p = dlabel( p, lf );
746: if( t<0 ) p = dlabel( p, lt );
747: return( p );
748:
749: case QUEST:
750: lf = f<0 ? getlab() : f;
751: lt = t<0 ? getlab() : t;
752: p->in.left = condit( p->in.left, CCC, -1, l=getlab() );
753: q = p->in.right;
754: q1 = condit( q->in.left, goal, lt, lf );
755: q->in.left = dlabel( q1, l );
756: q->in.right = condit( q->in.right, goal, t, f );
757: p->tn.op = COMOP;
758: q->tn.op = COMOP;
759: if( t<0 ) p = dlabel( p, lt );
760: if( f<0 ) p = dlabel( p, lf );
761: return( p );
762:
763: default:
764: /* get the condition codes, generate the branch */
765: switch( optype(o) )
766: {
767: case BITYPE:
768: p->in.right = condit( p->in.right, NRGS, -1, -1 );
769: case UTYPE:
770: p->in.left = condit( p->in.left, NRGS, -1, -1 );
771: }
772: if( t>=0 ) p = genbr( NE, t, p );
773: if( f>=0 ) p = genbr( (t>=0)?0:EQ, f, p );
774: return( p );
775: }
776: }
777:
778: # ifndef TWOPASS
779:
780: p2compile( p )
781: register NODE *p;
782: {
783: if( lflag ) lineid( lineno, ftitle );
784: tmpoff = 0; /* expression at top level reuses temps */
785: /* generate code for the tree p */
786:
787: # ifdef MYREADER
788: MYREADER(p); /* do your own laundering of the input */
789: # endif
790: /* eliminate the conditionals */
791: # ifndef NODBG
792: if( p && odebug>2 ) e2print(p);
793: # endif
794: p = condit( p, CEFF, -1, -1 );
795: if( p )
796: {
797: /* expression does something */
798: /* generate the code */
799: # ifndef NODBG
800: if( odebug>2 ) e2print(p);
801: # endif
802: codgen( p );
803: }
804: # ifndef NODBG
805: else if( odebug>1 ) printf( "null effect\n" );
806: # endif
807: allchk();
808: /* tcheck will be done by the first pass at the end of a ftn. */
809: /* first pass will do it... */
810: }
811:
812: p2bbeg( aoff, myreg )
813: register aoff,myreg;
814: {
815: static int myftn = -1;
816: SETOFF( aoff, ALSTACK );
817: if( myftn != ftnno )
818: {
819: /* beginning of function */
820: maxboff = aoff;
821: myftn = ftnno;
822: maxtemp = 0;
823: maxarg = 0;
824: }
825: else
826: {
827: if( aoff > maxboff ) maxboff = aoff;
828: }
829: # ifdef SETREGS
830: SETREGS(myreg);
831: # endif
832: }
833:
834: p2bend()
835: {
836: SETOFF( maxboff, ALSTACK );
837: SETOFF( maxarg, ALSTACK );
838: SETOFF( maxtemp, ALSTACK );
839: eobl2();
840: maxboff = maxarg = maxtemp = 0;
841: }
842:
843: # endif
844:
845: char *cnames[] =
846: {
847: "CEFF",
848: "NRGS",
849: "CCC",
850: 0,
851: };
852:
853: prgoal( goal )
854: register goal;
855: {
856: /* print a nice-looking description of goal */
857:
858: register i, flag;
859:
860: flag = 0;
861: for( i=0; cnames[i]; ++i )
862: {
863: if( goal & (1<<i) )
864: {
865: if( flag ) printf( "|" );
866: ++flag;
867: printf( cnames[i] );
868: }
869: }
870: if( !flag ) printf( "?%o", goal );
871:
872: }
873:
874: #ifndef NODBG
875: e2print( p )
876: register NODE *p;
877: {
878: printf( "\n********* costs=(0,...,NRGS;EFF;TEMP;CC)\n" );
879: e22print( p ,"T");
880: printf("=========\n");
881: }
882:
883: e22print( p ,s)
884: register NODE *p;
885: char *s;
886: {
887: static down=0;
888: register ty;
889:
890: ty = optype( p->tn.op );
891: if( ty == BITYPE )
892: {
893: ++down;
894: e22print( p->in.right ,"R");
895: --down;
896: }
897: e222print( down, p, s );
898:
899: if( ty != LTYPE )
900: {
901: ++down;
902: e22print( p->in.left, "L" );
903: --down;
904: }
905: }
906:
907: e222print( down, p, s )
908: NODE *p;
909: char *s;
910: {
911: /* print one node */
912: int i, d;
913:
914: for( d=down; d>1; d -= 2 ) printf( "\t" );
915: if( d ) printf( " " );
916:
917: printf( "%s.%d) op= '%s'",s, (int)(p-node), opst[p->in.op] );
918: switch( p->in.op )
919: {
920: /* special cases */
921: case REG:
922: printf( " %s", rnames[p->tn.rval] );
923: break;
924:
925: case ICON:
926: case NAME:
927: case VAUTO:
928: case VPARAM:
929: case TEMP:
930: printf( " " );
931: adrput( p );
932: break;
933:
934: case STCALL:
935: case UNARY STCALL:
936: printf( " args=%d", p->stn.argsize );
937: case STARG:
938: case STASG:
939: printf( " size=%d", p->stn.stsize );
940: printf( " align=%d", p->stn.stalign );
941: break;
942:
943: case GENBR:
944: printf( " %d (%s)", p->bn.label, opst[p->bn.lop] );
945: break;
946:
947: case CALL:
948: case UNARY CALL:
949: printf( " args=%d", p->stn.argsize );
950: break;
951:
952: case GENUBR:
953: case GENLAB:
954: printf( " %d", p->bn.label );
955: break;
956:
957: case FUNARG:
958: printf( " offset=%d", p->tn.rval );
959:
960: }
961:
962: printf( ", " );
963: t2print( p->in.type );
964: printf( ", c=[" );
965: for( i=0; i<NRGS; ++i ) cprt( p->in.cst[i], "," );
966: cprt( p->in.cst[NRGS], "; " );
967: cprt( p->in.cst[CEFF], "; " );
968: cprt( p->in.cst[CTEMP], "; " );
969: cprt( p->in.cst[CCC], "]" );
970: if( p->tn.goal == CEFF ) printf( " (EFF)\n" );
971: else if( p->tn.goal == CCC ) printf( " (CC)\n" );
972: else if( p->tn.goal != NRGS ) printf( "(BAD GOAL: %d)\n", p->tn.goal );
973: else printf( "\n" );
974: }
975:
976: t2print( t )
977: TWORD t;
978: {
979: int i;
980: static struct {
981: TWORD mask;
982: char * string;
983: } t2tab[] = {
984: TANY, "ANY",
985: TINT, "INT",
986: TUNSIGNED, "UNSIGNED",
987: TCHAR, "CHAR",
988: TUCHAR, "UCHAR",
989: TSHORT, "SHORT",
990: TUSHORT, "USHORT",
991: TLONG, "LONG",
992: TULONG, "ULONG",
993: TFLOAT, "FLOAT",
994: TDOUBLE, "DOUBLE",
995: TPOINT, "POINTER",
996: TPOINT2, "POINTER2",
997: TSTRUCT, "STRUCT",
998: TVOID, "VOID",
999: 0, 0
1000: };
1001:
1002: for( i=0; t && t2tab[i].mask; ++i ) {
1003: if( (t&t2tab[i].mask) == t2tab[i].mask ) {
1004: printf( " %s", t2tab[i].string );
1005: t ^= t2tab[i].mask;
1006: }
1007: }
1008: }
1009:
1010: # else
1011: e2print( p )
1012: NODE *p;
1013: {
1014: werror( "e2print not compiled" );
1015: }
1016: e222print( p, s )
1017: NODE *p;
1018: char *s;
1019: {
1020: werror( "e222print not compiled" );
1021: }
1022: # endif
1023: cprt( c, s )
1024: register char *s;
1025: register c;
1026: {
1027: if( c >= INFINITY ) printf( "*%s", s );
1028: else printf( "%d%s", c, s );
1029: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.