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