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