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