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