|
|
1.1 root 1: static char *sccsid ="%W% (Berkeley) %G%";
2: # include "mfile2"
3: # include "ctype.h"
4: /* a lot of the machine dependent parts of the second pass */
5:
6: # define BITMASK(n) ((1L<<n)-1)
7:
8: where(c){
9: fprintf( stderr, "%s, line %d: ", filename, lineno );
10: }
11:
12: lineid( l, fn ) char *fn; {
13: /* identify line l and file fn */
14: printf( "# line %d, file %s\n", l, fn );
15: }
16:
17:
18: eobl2(){
19: OFFSZ spoff; /* offset from stack pointer */
20: #ifdef FORT
21: spoff = maxoff;
22: if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
23: spoff /= SZCHAR;
24: SETOFF(spoff,4);
25: #ifndef FLEXNAMES
26: printf( " .set .F%d,%ld\n", ftnno, spoff );
27: #else
28: /* SHOULD BE L%d ... ftnno but must change pc/f77 */
29: printf( " .set LF%d,%ld\n", ftnno, spoff );
30: #endif
31: #else
32: extern int ftlab1, ftlab2;
33:
34: spoff = maxoff;
35: if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
36: spoff /= SZCHAR;
37: SETOFF(spoff,4);
38: printf( "L%d:\n", ftlab1);
39: if( spoff!=0 )
40: if( spoff < 64 )
41: printf( " subl2 $%ld,sp\n", spoff);
42: else
43: printf( " movab -%ld(sp),sp\n", spoff);
44: printf( " jbr L%d\n", ftlab2);
45: #endif
46: maxargs = -1;
47: }
48:
49: struct hoptab { int opmask; char * opstring; } ioptab[] = {
50:
51: ASG PLUS, "add",
52: ASG MINUS, "sub",
53: ASG MUL, "mul",
54: ASG DIV, "div",
55: ASG OR, "bis",
56: ASG ER, "xor",
57: ASG AND, "bic",
58: PLUS, "add",
59: MINUS, "sub",
60: MUL, "mul",
61: DIV, "div",
62: OR, "bis",
63: ER, "xor",
64: AND, "bic",
65: -1, "" };
66:
67: hopcode( f, o ){
68: /* output the appropriate string from the above table */
69:
70: register struct hoptab *q;
71:
72: for( q = ioptab; q->opmask>=0; ++q ){
73: if( q->opmask == o ){
74: printf( "%s", q->opstring );
75: /* tbl
76: if( f == 'F' ) printf( "e" );
77: else if( f == 'D' ) printf( "d" );
78: tbl */
79: /* tbl */
80: switch( f ) {
81: case 'L':
82: case 'W':
83: case 'B':
84: case 'D':
85: case 'F':
86: printf("%c", tolower(f));
87: break;
88:
89: }
90: /* tbl */
91: return;
92: }
93: }
94: cerror( "no hoptab for %s", opst[o] );
95: }
96:
97: char *
98: rnames[] = { /* keyed to register number tokens */
99:
100: "r0", "r1",
101: "r2", "r3", "r4", "r5",
102: "r6", "r7", "r8", "r9", "r10", "r11",
103: "ap", "fp", "sp", "pc",
104:
105: };
106:
107: int rstatus[] = {
108: SAREG|STAREG, SAREG|STAREG,
109: SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,
110: SAREG, SAREG, SAREG, SAREG, SAREG, SAREG,
111: SAREG, SAREG, SAREG, SAREG,
112:
113: };
114:
115: tlen(p) NODE *p;
116: {
117: switch(p->in.type) {
118: case CHAR:
119: case UCHAR:
120: return(1);
121:
122: case SHORT:
123: case USHORT:
124: return(2);
125:
126: case DOUBLE:
127: return(8);
128:
129: default:
130: return(4);
131: }
132: }
133:
134: mixtypes(p, q) NODE *p, *q;
135: {
136: register tp, tq;
137:
138: tp = p->in.type;
139: tq = q->in.type;
140:
141: return( (tp==FLOAT || tp==DOUBLE) !=
142: (tq==FLOAT || tq==DOUBLE) );
143: }
144:
145: prtype(n) NODE *n;
146: {
147: switch (n->in.type)
148: {
149: case DOUBLE:
150: printf("d");
151: return;
152:
153: case FLOAT:
154: printf("f");
155: return;
156:
157: case LONG:
158: case ULONG:
159: case INT:
160: case UNSIGNED:
161: printf("l");
162: return;
163:
164: case SHORT:
165: case USHORT:
166: printf("w");
167: return;
168:
169: case CHAR:
170: case UCHAR:
171: printf("b");
172: return;
173:
174: default:
175: if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type");
176: else {
177: printf("l");
178: return;
179: }
180: }
181: }
182:
183: zzzcode( p, c ) register NODE *p; {
184: register m;
185: CONSZ val;
186: switch( c ){
187:
188: case 'N': /* logical ops, turned into 0-1 */
189: /* use register given by register 1 */
190: cbgen( 0, m=getlab(), 'I' );
191: deflab( p->bn.label );
192: printf( " clrl %s\n", rnames[getlr( p, '1' )->tn.rval] );
193: deflab( m );
194: return;
195:
196: case 'I':
197: case 'P':
198: cbgen( p->in.op, p->bn.label, c );
199: return;
200:
201: case 'A':
202: {
203: register NODE *l, *r;
204:
205: if (xdebug) eprint(p, 0, &val, &val);
206: r = getlr(p, 'R');
207: if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL)
208: {
209: l = resc;
210: l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT);
211: }
212: else
213: l = getlr(p, 'L');
214: if (r->in.op == ICON)
215: if(r->in.name[0] == '\0')
216: {
217: if (r->tn.lval == 0)
218: {
219: printf("clr");
220: prtype(l);
221: printf(" ");
222: adrput(l);
223: return;
224: }
225: if (r->tn.lval < 0 && r->tn.lval >= -63)
226: {
227: printf("mneg");
228: prtype(l);
229: r->tn.lval = -r->tn.lval;
230: goto ops;
231: }
232: r->in.type = (r->tn.lval < 0 ?
233: (r->tn.lval >= -128 ? CHAR
234: : (r->tn.lval >= -32768 ? SHORT
235: : INT )) : r->in.type);
236: r->in.type = (r->tn.lval >= 0 ?
237: (r->tn.lval <= 63 ? INT
238: : ( r->tn.lval <= 127 ? CHAR
239: : (r->tn.lval <= 255 ? UCHAR
240: : (r->tn.lval <= 32767 ? SHORT
241: : (r->tn.lval <= 65535 ? USHORT
242: : INT ))))) : r->in.type );
243: }
244: else
245: {
246: printf("moval");
247: printf(" ");
248: acon(r);
249: printf(",");
250: adrput(l);
251: return;
252: }
253:
254: if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE)
255: {
256: if( tlen(l) < tlen(r) )
257: {
258: if (!mixtypes(l,r))
259: {
260: !ISUNSIGNED(l->in.type)?
261: printf("cvt"):
262: printf("movz");
263: prtype(l);
264: printf("l");
265: goto ops;
266: }
267: else
268: {
269: printf("cvt");
270: prtype(r);
271: prtype(l);
272: printf(" ");
273: adrput(r);
274: printf(",");
275: adrput(l);
276: printf("cvt");
277: prtype(l);
278: printf("l");
279: printf(" ");
280: adrput(l);
281: printf(",");
282: adrput(l);
283: return;
284: }
285: }
286: else
287: {
288: l->in.type = INT;
289: }
290: }
291: if (!mixtypes(l,r))
292: {
293: if (tlen(l) == tlen(r))
294: {
295: printf("mov");
296: prtype(l);
297: goto ops;
298: }
299: else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type))
300: {
301: printf("movz");
302: }
303: else
304: {
305: printf("cvt");
306: }
307: }
308: else
309: {
310: printf("cvt");
311: }
312: prtype(r);
313: prtype(l);
314: ops:
315: printf(" ");
316: adrput(r);
317: printf(",");
318: adrput(l);
319: return;
320: }
321:
322: case 'B': /* get oreg value in temp register for left shift */
323: {
324: register NODE *r;
325: if (xdebug) eprint(p, 0, &val, &val);
326: r = p->in.right;
327: if( tlen(r) == sizeof(int) && r->in.type != FLOAT )
328: printf("movl");
329: else {
330: printf("cvt");
331: prtype(r);
332: printf("l");
333: }
334: return;
335: }
336:
337: case 'C': /* num words pushed on arg stack */
338: {
339: extern int gc_numbytes;
340: extern int xdebug;
341:
342: if (xdebug) printf("->%d<-",gc_numbytes);
343:
344: printf("$%d", gc_numbytes/(SZLONG/SZCHAR) );
345: return;
346: }
347:
348: case 'D': /* INCR and DECR */
349: zzzcode(p->in.left, 'A');
350: printf("\n ");
351:
352: case 'E': /* INCR and DECR, FOREFF */
353: if (p->in.right->tn.lval == 1)
354: {
355: printf("%s", (p->in.op == INCR ? "inc" : "dec") );
356: prtype(p->in.left);
357: printf(" ");
358: adrput(p->in.left);
359: return;
360: }
361: printf("%s", (p->in.op == INCR ? "add" : "sub") );
362: prtype(p->in.left);
363: printf("2 ");
364: adrput(p->in.right);
365: printf(",");
366: adrput(p->in.left);
367: return;
368:
369: case 'F': /* register type of right operand */
370: {
371: register NODE *n;
372: extern int xdebug;
373: register int ty;
374:
375: n = getlr( p, 'R' );
376: ty = n->in.type;
377:
378: if (xdebug) printf("->%d<-", ty);
379:
380: if ( ty==DOUBLE) printf("d");
381: else if ( ty==FLOAT ) printf("f");
382: else printf("l");
383: return;
384: }
385:
386: case 'L': /* type of left operand */
387: case 'R': /* type of right operand */
388: {
389: register NODE *n;
390: extern int xdebug;
391:
392: n = getlr ( p, c);
393: if (xdebug) printf("->%d<-", n->in.type);
394:
395: prtype(n);
396: return;
397: }
398:
399: case 'Z': /* complement mask for bit instr */
400: printf("$%ld", ~p->in.right->tn.lval);
401: return;
402:
403: case 'U': /* 32 - n, for unsigned right shifts */
404: printf("$%d", 32 - p->in.right->tn.lval );
405: return;
406:
407: case 'T': /* rounded structure length for arguments */
408: {
409: int size;
410:
411: size = p->stn.stsize;
412: SETOFF( size, 4);
413: printf("$%d", size);
414: return;
415: }
416:
417: case 'S': /* structure assignment */
418: {
419: register NODE *l, *r;
420: register size;
421:
422: if( p->in.op == STASG ){
423: l = p->in.left;
424: r = p->in.right;
425:
426: }
427: else if( p->in.op == STARG ){ /* store an arg into a temporary */
428: l = getlr( p, '3' );
429: r = p->in.left;
430: }
431: else cerror( "STASG bad" );
432:
433: if( r->in.op == ICON ) r->in.op = NAME;
434: else if( r->in.op == REG ) r->in.op = OREG;
435: else if( r->in.op != OREG ) cerror( "STASG-r" );
436:
437: size = p->stn.stsize;
438:
439: if( size <= 0 || size > 65535 )
440: cerror("structure size <0=0 or >65535");
441:
442: switch(size) {
443: case 1:
444: printf(" movb ");
445: break;
446: case 2:
447: printf(" movw ");
448: break;
449: case 4:
450: printf(" movl ");
451: break;
452: case 8:
453: printf(" movq ");
454: break;
455: default:
456: printf(" movc3 $%d,", size);
457: break;
458: }
459: adrput(r);
460: printf(",");
461: adrput(l);
462: printf("\n");
463:
464: if( r->in.op == NAME ) r->in.op = ICON;
465: else if( r->in.op == OREG ) r->in.op = REG;
466:
467: }
468: break;
469:
470: default:
471: cerror( "illegal zzzcode" );
472: }
473: }
474:
475: rmove( rt, rs, t ){
476: printf( " %s %s,%s\n",
477: (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
478: rnames[rs], rnames[rt] );
479: }
480:
481: struct respref
482: respref[] = {
483: INTAREG|INTBREG, INTAREG|INTBREG,
484: INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON,
485: INTEMP, INTEMP,
486: FORARG, FORARG,
487: INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM,
488: 0, 0 };
489:
490: setregs(){ /* set up temporary registers */
491: fregs = 6; /* tbl- 6 free regs on VAX (0-5) */
492: ;
493: }
494:
495: szty(t){ /* size, in registers, needed to hold thing of type t */
496: return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
497: }
498:
499: rewfld( p ) NODE *p; {
500: return(1);
501: }
502:
503: callreg(p) NODE *p; {
504: return( R0 );
505: }
506:
507: base( p ) register NODE *p; {
508: register int o = p->in.op;
509:
510: if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */
511: if( o==REG ) return( p->tn.rval );
512: if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON)
513: return( p->in.left->tn.rval );
514: if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) )
515: return( p->tn.rval + 0200*1 );
516: if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 );
517: if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 );
518: if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG
519: && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) )
520: return( p->in.left->in.left->tn.rval + 0200*(1+2) );
521: return( -1 );
522: }
523:
524: offset( p, tyl ) register NODE *p; int tyl; {
525:
526: if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval );
527: if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) &&
528: (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0')
529: && (1<<p->in.right->tn.lval)==tyl))
530: return( p->in.left->tn.rval );
531: return( -1 );
532: }
533:
534: makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
535: register NODE *t;
536: register int i;
537: NODE *f;
538:
539: p->in.op = OREG;
540: f = p->in.left; /* have to free this subtree later */
541:
542: /* init base */
543: switch (q->in.op) {
544: case ICON:
545: case REG:
546: case OREG:
547: t = q;
548: break;
549:
550: case MINUS:
551: q->in.right->tn.lval = -q->in.right->tn.lval;
552: case PLUS:
553: t = q->in.right;
554: break;
555:
556: case INCR:
557: case ASG MINUS:
558: t = q->in.left;
559: break;
560:
561: case UNARY MUL:
562: t = q->in.left->in.left;
563: break;
564:
565: default:
566: cerror("illegal makeor2");
567: }
568:
569: p->tn.lval = t->tn.lval;
570: #ifndef FLEXNAMES
571: for(i=0; i<NCHNAM; ++i)
572: p->in.name[i] = t->in.name[i];
573: #else
574: p->in.name = t->in.name;
575: #endif
576:
577: /* init offset */
578: p->tn.rval = R2PACK( (b & 0177), o, (b>>7) );
579:
580: tfree(f);
581: return;
582: }
583:
584: canaddr( p ) NODE *p; {
585: register int o = p->in.op;
586:
587: if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1);
588: return(0);
589: }
590:
591: shltype( o, p ) register NODE *p; {
592: return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) );
593: }
594:
595: flshape( p ) register NODE *p; {
596: return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON ||
597: (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) );
598: }
599:
600: shtemp( p ) register NODE *p; {
601: if( p->in.op == STARG ) p = p->in.left;
602: return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) );
603: }
604:
605: shumul( p ) register NODE *p; {
606: register o;
607: extern int xdebug;
608:
609: if (xdebug) {
610: printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op);
611: printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval);
612: }
613:
614:
615: o = p->in.op;
616: if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM );
617:
618: if( ( o == INCR || o == ASG MINUS ) &&
619: ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) &&
620: p->in.right->in.name[0] == '\0' )
621: {
622: switch (p->in.left->in.type)
623: {
624: case CHAR|PTR:
625: case UCHAR|PTR:
626: o = 1;
627: break;
628:
629: case SHORT|PTR:
630: case USHORT|PTR:
631: o = 2;
632: break;
633:
634: case INT|PTR:
635: case UNSIGNED|PTR:
636: case LONG|PTR:
637: case ULONG|PTR:
638: case FLOAT|PTR:
639: o = 4;
640: break;
641:
642: case DOUBLE|PTR:
643: o = 8;
644: break;
645:
646: default:
647: if ( ISPTR(p->in.left->in.type) ) {
648: o = 4;
649: break;
650: }
651: else return(0);
652: }
653: return( p->in.right->tn.lval == o ? STARREG : 0);
654: }
655:
656: return( 0 );
657: }
658:
659: adrcon( val ) CONSZ val; {
660: printf( "$" );
661: printf( CONFMT, val );
662: }
663:
664: conput( p ) register NODE *p; {
665: switch( p->in.op ){
666:
667: case ICON:
668: acon( p );
669: return;
670:
671: case REG:
672: printf( "%s", rnames[p->tn.rval] );
673: return;
674:
675: default:
676: cerror( "illegal conput" );
677: }
678: }
679:
680: insput( p ) register NODE *p; {
681: cerror( "insput" );
682: }
683:
684: upput( p ) register NODE *p; {
685: cerror( "upput" );
686: }
687:
688: adrput( p ) register NODE *p; {
689: register int r;
690: /* output an address, with offsets, from p */
691:
692: if( p->in.op == FLD ){
693: p = p->in.left;
694: }
695: switch( p->in.op ){
696:
697: case NAME:
698: acon( p );
699: return;
700:
701: case ICON:
702: /* addressable value of the constant */
703: printf( "$" );
704: acon( p );
705: return;
706:
707: case REG:
708: printf( "%s", rnames[p->tn.rval] );
709: return;
710:
711: case OREG:
712: r = p->tn.rval;
713: if( R2TEST(r) ){ /* double indexing */
714: register int flags;
715:
716: flags = R2UPK3(r);
717: if( flags & 1 ) printf("*");
718: if( flags & 4 ) printf("-");
719: if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p);
720: if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
721: if( flags & 2 ) printf("+");
722: printf( "[%s]", rnames[R2UPK2(r)] );
723: return;
724: }
725: if( r == AP ){ /* in the argument region */
726: if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" );
727: printf( CONFMT, p->tn.lval );
728: printf( "(ap)" );
729: return;
730: }
731: if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p );
732: printf( "(%s)", rnames[p->tn.rval] );
733: return;
734:
735: case UNARY MUL:
736: /* STARNM or STARREG found */
737: if( tshape(p, STARNM) ) {
738: printf( "*" );
739: adrput( p->in.left);
740: }
741: else { /* STARREG - really auto inc or dec */
742: register NODE *q;
743:
744: /* tbl
745: p = p->in.left;
746: p->in.left->in.op = OREG;
747: if( p->in.op == INCR ) {
748: adrput( p->in.left );
749: printf( "+" );
750: }
751: else {
752: printf( "-" );
753: adrput( p->in.left );
754: }
755: tbl */
756: printf("%s(%s)%s", (p->in.left->in.op==INCR ? "" : "-"),
757: rnames[p->in.left->in.left->tn.rval],
758: (p->in.left->in.op==INCR ? "+" : "") );
759: p->in.op = OREG;
760: p->tn.rval = p->in.left->in.left->tn.rval;
761: q = p->in.left;
762: p->tn.lval = (p->in.left->in.op == INCR ? -p->in.left->in.right->tn.lval : 0);
763: #ifndef FLEXNAMES
764: p->in.name[0] = '\0';
765: #else
766: p->in.name = "";
767: #endif
768: tfree(q);
769: }
770: return;
771:
772: default:
773: cerror( "illegal address" );
774: return;
775:
776: }
777:
778: }
779:
780: acon( p ) register NODE *p; { /* print out a constant */
781:
782: if( p->in.name[0] == '\0' ){
783: printf( CONFMT, p->tn.lval);
784: }
785: else if( p->tn.lval == 0 ) {
786: #ifndef FLEXNAMES
787: printf( "%.8s", p->in.name );
788: #else
789: printf( "%s", p->in.name );
790: #endif
791: }
792: else {
793: #ifndef FLEXNAMES
794: printf( "%.8s+", p->in.name );
795: #else
796: printf( "%s+", p->in.name );
797: #endif
798: printf( CONFMT, p->tn.lval );
799: }
800: }
801:
802: /*
803: aacon( p ) register NODE *p; { /* print out a constant */
804: /*
805:
806: if( p->in.name[0] == '\0' ){
807: printf( CONFMT, p->tn.lval);
808: return( 0 );
809: }
810: else if( p->tn.lval == 0 ) {
811: #ifndef FLEXNAMES
812: printf( "$%.8s", p->in.name );
813: #else
814: printf( "$%s", p->in.name );
815: #endif
816: return( 1 );
817: }
818: else {
819: printf( "$(" );
820: printf( CONFMT, p->tn.lval );
821: printf( "+" );
822: #ifndef FLEXNAMES
823: printf( "%.8s)", p->in.name );
824: #else
825: printf( "%s)", p->in.name );
826: #endif
827: return(1);
828: }
829: }
830: */
831:
832: genscall( p, cookie ) register NODE *p; {
833: /* structure valued call */
834: return( gencall( p, cookie ) );
835: }
836:
837: /* tbl */
838: int gc_numbytes;
839: /* tbl */
840:
841: gencall( p, cookie ) register NODE *p; {
842: /* generate the call given by p */
843: register NODE *p1, *ptemp;
844: register temp, temp1;
845: register m;
846:
847: if( p->in.right ) temp = argsize( p->in.right );
848: else temp = 0;
849:
850: if( p->in.op == STCALL || p->in.op == UNARY STCALL ){
851: /* set aside room for structure return */
852:
853: if( p->stn.stsize > temp ) temp1 = p->stn.stsize;
854: else temp1 = temp;
855: }
856:
857: if( temp > maxargs ) maxargs = temp;
858: SETOFF(temp1,4);
859:
860: if( p->in.right ){ /* make temp node, put offset in, and generate args */
861: ptemp = talloc();
862: ptemp->in.op = OREG;
863: ptemp->tn.lval = -1;
864: ptemp->tn.rval = SP;
865: #ifndef FLEXNAMES
866: ptemp->in.name[0] = '\0';
867: #else
868: ptemp->in.name = "";
869: #endif
870: ptemp->in.rall = NOPREF;
871: ptemp->in.su = 0;
872: genargs( p->in.right, ptemp );
873: ptemp->in.op = FREE;
874: }
875:
876: p1 = p->in.left;
877: if( p1->in.op != ICON ){
878: if( p1->in.op != REG ){
879: if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){
880: if( p1->in.op != NAME ){
881: order( p1, INAREG );
882: }
883: }
884: }
885: }
886:
887: /*
888: if( p1->in.op == REG && p->tn.rval == R5 ){
889: cerror( "call register overwrite" );
890: }
891: */
892: /* tbl
893: setup gc_numbytes so reference to ZC works */
894:
895: gc_numbytes = temp;
896: /* tbl */
897:
898: p->in.op = UNARY CALL;
899: m = match( p, INTAREG|INTBREG );
900: /* tbl
901: switch( temp ) {
902: case 0:
903: break;
904: case 2:
905: printf( " tst (sp)+\n" );
906: break;
907: case 4:
908: printf( " cmp (sp)+,(sp)+\n" );
909: break;
910: default:
911: printf( " add $%d,sp\n", temp);
912: }
913: tbl */
914: return(m != MDONE);
915: }
916:
917: /* tbl */
918: char *
919: ccbranches[] = {
920: " jeql L%d\n",
921: " jneq L%d\n",
922: " jleq L%d\n",
923: " jlss L%d\n",
924: " jgeq L%d\n",
925: " jgtr L%d\n",
926: " jlequ L%d\n",
927: " jlssu L%d\n",
928: " jgequ L%d\n",
929: " jgtru L%d\n",
930: };
931: /* tbl */
932:
933: cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */
934:
935: /* tbl */
936: if( o == 0 ) printf( " jbr L%d\n", lab );
937: /* tbl */
938: else {
939: if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
940: printf( ccbranches[o-EQ], lab );
941: }
942: }
943:
944: nextcook( p, cookie ) NODE *p; {
945: /* we have failed to match p with cookie; try another */
946: if( cookie == FORREW ) return( 0 ); /* hopeless! */
947: if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG );
948: if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
949: return( FORREW );
950: }
951:
952: lastchance( p, cook ) NODE *p; {
953: /* forget it! */
954: return(0);
955: }
956:
957: optim2( p ) register NODE *p; {
958: /* do local tree transformations and optimizations */
959:
960: register NODE *r;
961:
962: switch( p->in.op ) {
963:
964: case AND:
965: /* commute L and R to eliminate compliments and constants */
966: if( (p->in.left->in.op==ICON&&p->in.left->in.name[0]==0) || p->in.left->in.op==COMPL ) {
967: r = p->in.left;
968: p->in.left = p->in.right;
969: p->in.right = r;
970: }
971: case ASG AND:
972: /* change meaning of AND to ~R&L - bic on pdp11 */
973: r = p->in.right;
974: if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */
975: r->tn.lval = ~r->tn.lval;
976: }
977: else if( r->in.op==COMPL ) { /* ~~A => A */
978: r->in.op = FREE;
979: p->in.right = r->in.left;
980: }
981: else { /* insert complement node */
982: p->in.right = talloc();
983: p->in.right->in.op = COMPL;
984: p->in.right->in.rall = NOPREF;
985: p->in.right->in.type = r->in.type;
986: p->in.right->in.left = r;
987: p->in.right->in.right = NULL;
988: }
989: break;
990:
991: }
992: }
993:
994: NODE * addroreg(l)
995: /* OREG was built in clocal()
996: * for an auto or formal parameter
997: * now its address is being taken
998: * local code must unwind it
999: * back to PLUS/MINUS REG ICON
1000: * according to local conventions
1001: */
1002: {
1003: cerror("address of OREG taken");
1004: }
1005:
1006:
1007:
1008: # ifndef ONEPASS
1009: main( argc, argv ) char *argv[]; {
1010: return( mainp2( argc, argv ) );
1011: }
1012: # endif
1013:
1014:
1015: /* added by jwf */
1016: struct functbl {
1017: int fop;
1018: TWORD ftype;
1019: char *func;
1020: } opfunc[] = {
1021: DIV, TANY, "udiv",
1022: MOD, TANY, "urem",
1023: ASG DIV, TANY, "udiv",
1024: ASG MOD, TANY, "urem",
1025: 0, 0, 0 };
1026:
1027: hardops(p) register NODE *p; {
1028: /* change hard to do operators into function calls. */
1029: register NODE *q;
1030: register struct functbl *f;
1031: register o;
1032: register TWORD t;
1033:
1034: o = p->in.op;
1035: t = p->in.type;
1036: if( t!=UNSIGNED && t!=ULONG ) return;
1037:
1038: for( f=opfunc; f->fop; f++ ) {
1039: if( o==f->fop ) goto convert;
1040: }
1041: return;
1042:
1043: /* need to rewrite tree for ASG OP */
1044: /* must change ASG OP to a simple OP */
1045: convert:
1046: if( asgop( o ) ) {
1047: q = talloc();
1048: switch( p->in.op ) {
1049: case ASG DIV:
1050: q->in.op = DIV;
1051: break;
1052: case ASG MOD:
1053: q->in.op = MOD;
1054: break;
1055: }
1056: q->in.rall = NOPREF;
1057: q->in.type = p->in.type;
1058: q->in.left = tcopy(p->in.left);
1059: q->in.right = p->in.right;
1060: p->in.op = ASSIGN;
1061: p->in.right = q;
1062: zappost(q->in.left); /* remove post-INCR(DECR) from new node */
1063: fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */
1064: p = q;
1065:
1066: }
1067:
1068: /* build comma op for args to function */
1069: q = talloc();
1070: q->in.op = CM;
1071: q->in.rall = NOPREF;
1072: q->in.type = INT;
1073: q->in.left = p->in.left;
1074: q->in.right = p->in.right;
1075: p->in.op = CALL;
1076: p->in.right = q;
1077:
1078: /* put function name in left node of call */
1079: p->in.left = q = talloc();
1080: q->in.op = ICON;
1081: q->in.rall = NOPREF;
1082: q->in.type = INCREF( FTN + p->in.type );
1083: #ifndef FLEXNAMES
1084: strcpy( q->in.name, f->func );
1085: #else
1086: q->in.name = f->func;
1087: #endif
1088: q->tn.lval = 0;
1089: q->tn.rval = 0;
1090:
1091: return;
1092:
1093: }
1094:
1095: zappost(p) NODE *p; {
1096: /* look for ++ and -- operators and remove them */
1097:
1098: register o, ty;
1099: register NODE *q;
1100: o = p->in.op;
1101: ty = optype( o );
1102:
1103: switch( o ){
1104:
1105: case INCR:
1106: case DECR:
1107: q = p->in.left;
1108: p->in.right->in.op = FREE; /* zap constant */
1109: ncopy( p, q );
1110: q->in.op = FREE;
1111: return;
1112:
1113: }
1114:
1115: if( ty == BITYPE ) zappost( p->in.right );
1116: if( ty != LTYPE ) zappost( p->in.left );
1117: }
1118:
1119: fixpre(p) NODE *p; {
1120:
1121: register o, ty;
1122: o = p->in.op;
1123: ty = optype( o );
1124:
1125: switch( o ){
1126:
1127: case ASG PLUS:
1128: p->in.op = PLUS;
1129: break;
1130: case ASG MINUS:
1131: p->in.op = MINUS;
1132: break;
1133: }
1134:
1135: if( ty == BITYPE ) fixpre( p->in.right );
1136: if( ty != LTYPE ) fixpre( p->in.left );
1137: }
1138:
1139: myreader(p) register NODE *p; {
1140: walkf( p, hardops ); /* convert ops to function calls */
1141: canon( p ); /* expands r-vals for fileds */
1142: walkf( p, optim2 );
1143: /* jwf toff = 0; /* stack offset swindle */
1144: }
1145:
1146:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.