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