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