|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)c22.c 1.9 (Berkeley/CCI) 5/12/88";
3: #endif
4:
5: /*
6: * C object code improver-- third part
7: */
8:
9: #include "c2.h"
10: #include <stdio.h>
11: #include <ctype.h>
12:
13: rmove()
14: {
15: register struct node *p;
16: register int r, r1;
17:
18: clearreg();
19: for (p=first.forw; p!=0; p = p->forw) {
20: if (debug) {
21: printf("Regs: ");
22: for (r=0; r<=NREG; r++)
23: if (regs[r][0]) {
24: r1=regs[r][0];
25: printf("%d: %d%d %s\n", r, r1&0xF, r1>>4, regs[r]+1);
26: }
27: printf("-\n");
28: }
29: switch (p->op) {
30:
31: case CVT:
32: case MOVZ:
33: splitrand(p);
34: repladdr(p);
35: r = isreg(regs[RT1]);
36: r1 = isreg(regs[RT2]);
37: dest(regs[RT2],p->subop, p->op!=CVT || r<0);
38: if (r>=0 && r1>=0) {
39: p->op = MOV; p->subop = LONG;
40: p->pop = 0;
41: nchange++;
42: goto case_mov;
43: }
44: if(p->op == CVT) {
45: if (r1>=0) savereg(r1, regs[RT1], p->subop);
46: } else
47: ccloc[0] = 0;
48: break;
49:
50: case MOV:
51: case_mov:
52: splitrand(p);
53: if ((r = findrand(regs[RT1],p->subop)) >= 0) {
54: if (r == isreg(regs[RT2]))
55: if(p->forw->op!=CBR) {
56: delnode(p); redunm++; nchange++; break;
57: } else {
58: p->op=TST; p->pop=0;
59: while(*p->code++ != ',');
60: redunm++; nchange++;
61: goto case_tst;
62: }
63: }
64: repladdr(p);
65: r = isreg(regs[RT1]);
66: r1 = isreg(regs[RT2]);
67: dest(regs[RT2],p->subop, 1);
68: if ((regs[ACC][0]) && equstr(regs[RT2],regs[ACC]+1))
69: *(short *)(regs[ACC]) = 0;
70: if (r>=0) {
71: if (r1>=0) {
72: if (r == r1 && p->forw->op!=CBR) {
73: delnode(p); redunm++; nchange++;
74: break;
75: }
76: if(regs[r][0])
77: savereg(r1, regs[r]+1, p->subop);
78: } else
79: savereg(r, regs[RT2], p->subop);
80: } else if (r1>=0)
81: savereg(r1, regs[RT1], p->subop);
82: else
83: setcon(regs[RT1], regs[RT2], p->subop);
84: break;
85:
86: /* .rx,.wx or .rx,.rx,.wx */
87: case ADD:
88: case SUB:
89: case AND:
90: case OR:
91: case XOR:
92: case MUL:
93: case DIV:
94: #ifdef EMOD
95: case EDIV:
96: case EMOD:
97: #endif EMOD
98: case SHAL:
99: case SHAR:
100: case SHL:
101: case SHR:
102: case ADDA:
103: case SUBA:
104: /* .rx,.wx */
105: case MFPR:
106: case COM:
107: case NEG:
108: splitrand(p);
109: repladdr(p);
110: dest(lastrand,p->subop, p->op!=ADDA && p->op!=SUBA);
111: break;
112:
113: /* .mx or .wx */
114: case STF:
115: if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
116: delnode(p);
117: nst++; nchange++; break;
118: }
119: savereg(ACC, p->code, p->subop);
120: case INC:
121: case DEC:
122: case CVFL:
123: dest(p->code,p->subop, 1);
124: break;
125:
126: case CLR:
127: dest(p->code,p->subop, 1);
128: if ((regs[ACC][0]) && equstr(p->code,regs[ACC]+1))
129: *(short *)(regs[ACC]) = 0;
130: if ((r = isreg(p->code)) < 0)
131: setcon("$0", p->code, p->subop);
132: else
133: savereg(r, "$0", p->subop);
134: break;
135:
136: /* .rx */
137: case LDF:
138: if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
139: delnode(p);
140: nld++; nchange++; break;
141: }
142: savereg(ACC, p->code, p->subop);
143: goto case_tst;
144: case LNF:
145: if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
146: p->op = NEGF; p->pop = 0; p->code = 0;
147: regs[ACC][0] = 0;
148: break;
149: }
150: case CVLF:
151: case LDFD:
152: case ADDF:
153: case SUBF:
154: case MULF:
155: case DIVF:
156: regs[ACC][0] = 0;
157: case TST:
158: case_tst:
159: case PUSH:
160: splitrand(p);
161: lastrand=regs[RT1+1]; /* fool repladdr into doing 1 operand */
162: repladdr(p);
163: lastrand=regs[RT1];
164: if (p->op==TST && equstr(lastrand, ccloc+1)
165: && ((0xf&(ccloc[0]>>4))==p->subop || equtype(ccloc[0],p->subop))) {
166: delnode(p); nrtst++; nchange++; break;
167: }
168: if (p->op==PUSH && p->subop!=LONG &&
169: (isreg(lastrand)>=0 || *lastrand=='$')) {
170: p->subop = LONG;
171: p->pop = 0;
172: nchange++;
173: }
174: if (p->op==TST || p->op==PUSH)
175: setcc(lastrand,p->subop);
176: break;
177:
178: /* .rx,.rx,.rx */
179: case PROBE:
180: case CASE:
181: /* .rx,.rx */
182: case MTPR:
183: case CALLS:
184: case CALLF:
185: case CMP:
186: case BIT:
187: case CMPF:
188: case CMPF2:
189: splitrand(p);
190: /* fool repladdr into doing right number of operands */
191: lastrand=byondrd(p);
192: if (p->op==CALLF || p->op==CALLS) clearreg();
193: else repladdr(p);
194: case TSTF:
195: ccloc[0]=0;
196: case PUSHD:
197: break;
198:
199: /* acc only */
200: case CVDF:
201: case NEGF:
202: case SINF:
203: case COSF:
204: case ATANF:
205: case LOGF:
206: case SQRTF:
207: case EXPF:
208: regs[ACC][0] = 0;
209: break;
210:
211: #ifndef EMOD
212: /* .rx,.rx,.wx,.wx */
213: case EDIV:
214: splitrand(p);
215: lastrand = regs[RT3];
216: repladdr(p);
217: dest(regs[RT3], p->subop, 1);
218: dest(regs[RT4], p->subop, 0);
219: break;
220: #endif EMOD
221:
222: /* .rx,.rx,.rx,wx */
223: case EMUL:
224: splitrand(p);
225: lastrand = regs[RT4];
226: repladdr(p);
227: dest(regs[RT4],QUAD, 1); /* fourth operand is a quad */
228: break;
229: case CBR:
230: if (p->subop>=JBC) {
231: splitrand(p);
232: lastrand=regs[RT3]; /* 2 operands can be optimized */
233: repladdr(p);
234: ccloc[0] = 0;
235: } else
236: reduncbr(p);
237: break;
238:
239: case JBR:
240: redunbr(p);
241:
242: default:
243: clearreg();
244: }
245: }
246: }
247:
248: jumpsw()
249: {
250: register struct node *p, *p1, *pt;
251: register int t, nj;
252:
253: t = 0;
254: nj = 0;
255: for (p=first.forw; p!=0; p = p->forw)
256: p->seq = ++t;
257: for (p=first.forw; p!=0; p = p1) {
258: p1 = p->forw;
259: if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
260: && abs(p->seq - p->ref->seq) > abs(p1->seq - p1->ref->seq)) {
261: if (p->ref==p1->ref)
262: continue;
263: p->subop = revbr[p->subop];
264: p->pop=0;
265: pt = p1->ref;
266: p1->ref = p->ref;
267: p->ref = pt;
268: t = p1->labno;
269: p1->labno = p->labno;
270: p->labno = t;
271: #ifdef COPYCODE
272: if (p->labno == 0) {
273: pt = (struct node *)p1->code; p1->code = p->code; p->code = (char *)pt;
274: }
275: #endif
276: nrevbr++;
277: nj++;
278: }
279: }
280: return(nj);
281: }
282:
283: addaob()
284: {
285: register struct node *p, *p1, *p2, *p3;
286:
287: for (p = &first; (p1 = p->forw)!=0; p = p1) {
288: if (p->op==INC && p->subop==LONG) {
289: if (p1->op==LABEL && p1->refc==1 && p1->forw->op==CMP && p1->forw->subop==LONG
290: && (p2=p1->forw->forw)->op==CBR && p2->subop==JLE
291: && (p3=p2->ref->back)->op==JBR && p3->subop==0 && p3->ref==p1
292: && p3->forw->op==LABEL && p3->forw==p2->ref) {
293: /* change INC LAB: CMP to LAB: INC CMP */
294: p->back->forw=p1; p1->back=p->back;
295: p->forw=p1->forw; p1->forw->back=p;
296: p->back=p1; p1->forw=p;
297: p1=p->forw;
298: /* adjust beginning value by 1 */
299: p2=alloc(sizeof first); p2->op = DEC; p2->subop = LONG;
300: p2->pop=0;
301: p2->forw=p3; p2->back=p3->back; p3->back->forw=p2;
302: p3->back=p2; p2->code=p->code; p2->labno=0;
303: }
304: if (p1->op==CMP && p1->subop==LONG &&
305: (p2=p1->forw)->op==CBR && p2->forw->op!=CBR) {
306: register char *cp1,*cp2;
307: splitrand(p1); if (!equstr(p->code,regs[RT1])) continue;
308: if ((p2->subop==JLE || p2->subop==JLT) &&
309: checkaobdisp(p2)){
310: if (p2->subop==JLE) p->op = AOBLEQ; else p->op = AOBLSS; p->subop = 0;
311: cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */
312: cp2=regs[RT2]; cp1=p->code; while (*cp2++= *cp1++); /* index */
313: p->pop=0; newcode(p);
314: p->labno = p2->labno; delnode(p2); delnode(p1); naob++;
315: }
316: }
317: }
318: }
319: }
320:
321: ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
322: register int log;
323: if (n==0 || n&(n-1)) return(-1); log=0;
324: for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}
325: }
326:
327: equop(p1, p2)
328: register struct node *p1, *p2;
329: {
330: register char *cp1, *cp2;
331:
332: if (p1->op != p2->op || p1->subop != p2->subop)
333: return(0);
334: if (p1->op == NIL && p1->subop == 0 && p1->pop != p2->pop)
335: return(0);
336: if (p1->op != NIL && ord(p1->op) < ord(MOV))
337: return(0);
338: switch (p1->op) {
339: case EROU: case JSW: case TEXT: case DATA:
340: case BSS: case ALIGN: case WGEN: case END:
341: /* sufficient? */
342: return(0);
343: }
344: if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
345: cp1 = p1->code;
346: cp2 = p2->code;
347: if (cp1==0 && cp2==0)
348: return(1);
349: if (cp1==0 || cp2==0)
350: return(0);
351: while (*cp1 == *cp2++)
352: if (*cp1++ == 0)
353: return(1);
354: return(0);
355: }
356:
357: delnode(p) register struct node *p; {
358: p->back->forw = p->forw;
359: p->forw->back = p->back;
360: }
361:
362: decref(p)
363: register struct node *p;
364: {
365: if (p && --p->refc <= 0) {
366: nrlab++; nchange++;
367: delnode(p);
368: }
369: }
370:
371: struct node *
372: nonlab(ap)
373: struct node *ap;
374: {
375: register struct node *p;
376:
377: p = ap;
378: while (p && p->op==LABEL)
379: p = p->forw;
380: return(p);
381: }
382:
383: clearuse() {
384: register struct node **i;
385: for (i=uses+NREG; i>uses;) *--i=0;
386: useacc = 0;
387: }
388:
389: clearreg() {
390: register char **i;
391: for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; }
392: conloc[0] = 0; ccloc[0] = 0;
393: }
394:
395: savereg(ai, s, type)
396: register char *s;
397: {
398: register char *p, *sp;
399:
400: sp = p = regs[ai];
401: /* if any indexing, must be parameter or local */
402: /* indirection (as in "*-4(fp)") is ok, however */
403: *p++ = type;
404: if (*s=='*' || *s=='$')
405: *p++ = *s++;
406: if (natural(s))
407: strcpy(p, s);
408: else {*sp = 0; return;}
409: }
410:
411: dest(s,type, ccflg)
412: register char *s;
413: {
414: register int i;
415:
416: if ((i = isreg(s)) >= 0) {
417: *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
418: if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD)
419: *(short *)(regs[i+1]) = 0;
420: }
421: for (i=NREG; --i>=0;)
422: if (regs[i][1]=='*' && equstr(s, regs[i]+2))
423: *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
424: while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
425: *(short *)(regs[i]) = 0;
426:
427: if (!natural(s)) {/* wild store, everything except constants vanishes */
428: for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
429: conloc[0] = 0; ccloc[0] = 0;
430: } else {
431: if(ccflg)setcc(s,type); /* natural destinations set condition codes */
432: if (equstr(s, conloc))
433: conloc[0] = 0;
434: }
435: }
436:
437: splitrand(p) struct node *p; {
438: /* separate operands at commas, set up 'regs' and 'lastrand' */
439: register char *p1, *p2; register char **preg;
440:
441: preg=regs+RT1;
442: if (p1=p->code) while (*p1) {
443: lastrand=p2= *preg++;
444: while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
445: *p2=0;
446: }
447: while (preg<(regs+RT1+5)) *(*preg++)=0;
448: }
449:
450: compat(have, want)
451: register int have, want;
452: {
453: register int hsrc, hdst;
454: extern int bitsize[];
455:
456: if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
457: hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
458: if (want>=QUAD)
459: return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]);
460: return(hsrc==want && hdst>=want && hdst<QUAD);
461: }
462:
463: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
464:
465: findrand(as, type)
466: char *as;
467: {
468: register char **i;
469: for (i = regs+NREG; --i>=regs;) {
470: if (**i && equstr(*i+1, as) && compat(**i,type))
471: return(i-regs);
472: }
473: return(-1);
474: }
475:
476: isreg(s)
477: register char *s;
478: {
479: if (*s++!='r' || !isdigit(*s++)) return(-1);
480: if (*s==0) return(*--s-'0');
481: if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
482: return(-1);
483: }
484:
485: /*
486: check()
487: {
488: register struct node *p, *lp;
489:
490: lp = &first;
491: for (p=first.forw; p!=0; p = p->forw) {
492: if (p->back != lp)
493: abort(-1);
494: lp = p;
495: }
496: }
497: */
498:
499: newcode(p) struct node *p; {
500: register char *p1,*p2,**preg;
501:
502: preg=regs+RT1; p2=line;
503: while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
504: *--p2=0;
505: p->code=copy(line);
506: }
507:
508: repladdr(p)
509: struct node *p;
510: {
511: register int r;
512: register char *p1;
513: register char **preg;
514: register int nrepl;
515:
516: preg=regs+RT1; nrepl=0;
517: while (lastrand!=(p1= *preg++))
518: if (0<=(r=findrand(p1,p->subop))) {
519: *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
520: nchange++; nrepl++; nsaddr++;
521: }
522: if (nrepl) newcode(p);
523: }
524:
525: /* conditional branches which are never/always taken */
526: reduncbr(p)
527: register struct node *p;
528: {
529: register struct node *p1;
530: register char *ap1, *ap2;
531:
532: p1 = p->back;
533: if (p1->op==CMP) {
534: splitrand(p1);
535: ap1 = findcon(regs[RT1], p1->subop);
536: ap2 = findcon(regs[RT2], p1->subop);
537: } else {
538: if(!ccloc[0])
539: return;
540: ap1 = findcon(ccloc+1, ccloc[0]);
541: ap2 = "$0";
542: }
543: switch (compare(p->subop, ap1, ap2)) {
544: case 0: /* branch never taken */
545: delnode(p);
546: nredunj++;
547: nchange++;
548: decref(p->ref);
549: if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
550: delnode(p1);
551: nrtst++;
552: }
553: break;
554: case 1: /* branch always taken */
555: p->op = JBR;
556: p->subop = 0;
557: p->pop = 0;
558: nchange++;
559: if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) {
560: delnode(p1);
561: nrtst++;
562: }
563: }
564: }
565:
566: /* a jump to a redundant compare (start of a 'for') */
567: redunbr(p)
568: register struct node *p;
569: {
570: register struct node *p1;
571: register char *ap1, *ap2;
572:
573: if ((p1 = p->ref) == 0)
574: return;
575: p1 = nonlab(p1);
576: if (p1->op==TST || p1->op==CMP)
577: splitrand(p1);
578: else
579: return;
580: if (p1->forw->op==CBR) {
581: ap1 = findcon(regs[RT1], p1->subop);
582: if (p1->op==TST)
583: ap2 = "$0";
584: else
585: ap2 = findcon(regs[RT2], p1->subop);
586: p1 = p1->forw;
587: if (compare(p1->subop, ap1, ap2) > 0) {
588: nredunj++;
589: nchange++;
590: decref(p->ref);
591: p->ref = p1->ref;
592: p->labno = p1->labno;
593: #ifdef COPYCODE
594: if (p->labno == 0)
595: p->code = p1->code;
596: if (p->ref)
597: #endif
598: p->ref->refc++;
599: }
600: } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
601: equtype(ccloc[0],p1->subop)) {
602: p1=insertl(p1->forw); decref(p->ref); p->ref=p1;
603: p->labno=p1->labno;
604: nrtst++; nchange++;
605: }
606: }
607:
608: char *
609: findcon(p, type)
610: register char *p;
611: {
612: register int r;
613:
614: if (*p=='$')
615: return(p);
616: if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
617: return(regs[r]+1);
618: if (equstr(p, conloc) && equtype(conloc[0], type))
619: return(conval+1);
620: return(p);
621: }
622:
623: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
624: compare(op, acp1, acp2)
625: char *acp1, *acp2;
626: {
627: register char *cp1, *cp2;
628: register int n1, n2, sign;
629:
630: cp1 = acp1;
631: cp2 = acp2;
632: if (*cp1++ != '$' || *cp2++ != '$')
633: return(-1);
634: n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
635: while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
636: n1 *= sign;
637: n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
638: while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
639: n2 *= sign;
640: if (*cp1=='+')
641: cp1++;
642: if (*cp2=='+')
643: cp2++;
644: do {
645: if (*cp1++ != *cp2)
646: return(-1);
647: } while (*cp2++);
648: switch(op) {
649:
650: case JEQ:
651: return(n1 == n2);
652: case JNE:
653: return(n1 != n2);
654: case JLE:
655: return(n1 <= n2);
656: case JGE:
657: return(n1 >= n2);
658: case JLT:
659: return(n1 < n2);
660: case JGT:
661: return(n1 > n2);
662: case JLO:
663: return((unsigned)n1 < (unsigned)n2);
664: case JHI:
665: return((unsigned)n1 > (unsigned)n2);
666: case JLOS:
667: return((unsigned)n1 <= (unsigned)n2);
668: case JHIS:
669: return((unsigned)n1 >= (unsigned)n2);
670: }
671: return(-1);
672: }
673:
674: setcon(cv, cl, type)
675: register char *cv, *cl;
676: {
677: register char *p;
678:
679: if (*cv != '$')
680: return;
681: if (!natural(cl))
682: return;
683: p = conloc;
684: while (*p++ = *cl++);
685: p = conval;
686: *p++ = type;
687: while (*p++ = *cv++);
688: }
689:
690: setcc(ap,type)
691: char *ap;
692: {
693: register char *p, *p1;
694:
695: p = ap;
696: if (!natural(p)) {
697: ccloc[0] = 0;
698: return;
699: }
700: p1 = ccloc;
701: *p1++ = type;
702: while (*p1++ = *p++);
703: }
704:
705: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
706: while (*p) if (*p++=='[') return(1);
707: return(0);
708: }
709:
710: natural(p)
711: register char *p;
712: {/* 1->simple local, parameter, global, or register; 0->otherwise */
713:
714: if (*p=='*' || *p=='(' || *p=='$')
715: return(0);
716: while (*p++);
717: p--;
718: if (*--p==']' || *p==')' &&
719: !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
720: return(0);
721: return(1);
722: }
723:
724: /*
725: ** Tell if an argument is most likely static.
726: */
727:
728: isstatic(cp)
729: register char *cp;
730: {
731: if (*cp == '_' || *cp == 'L')
732: return (1);
733: return (0);
734: }
735:
736:
737: checkaobdisp(p)
738: register struct node *p;
739: {
740: register struct node *q;
741: register int i;
742:
743:
744: if (!aobflag) return(1);
745: /* backward search */
746: i = 0;
747: q = p;
748: while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
749: {
750: if (p->ref == q)
751: return(1);
752: }
753:
754: /* forward search */
755: i = 0;
756: q = p;
757: while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
758: {
759: if (p->ref == q)
760: return(1);
761: }
762: return(0);
763: }
764:
765:
766: struct intleavetab intltab[] = {
767: ADDF, FLOAT, 1,
768: ADDF, DOUBLE, 1,
769: SUBF, FLOAT, 1,
770: SUBF, DOUBLE, 1,
771: MULF, FLOAT, 1,
772: MULF, DOUBLE, 1,
773: DIVF, FLOAT, 1,
774: DIVF, DOUBLE, 1,
775: SINF, FLOAT, 1,
776: COSF, FLOAT, 1,
777: ATANF, FLOAT, 1,
778: LOGF, FLOAT, 1,
779: SQRTF, FLOAT, 1,
780: EXPF, FLOAT, 1,
781: LDF, FLOAT, 0,
782: LDF, DOUBLE, 0,
783: LNF, FLOAT, 0,
784: LNF, DOUBLE, 0,
785: STF, FLOAT, 0,
786: CMPF, FLOAT, 0,
787: CMPF, DOUBLE, 0,
788: CMPF2, FLOAT, 0,
789: TSTF, FLOAT, 0,
790: TSTF, DOUBLE, 0,
791: PUSHD, DOUBLE, 0,
792: CVLF, U(LONG,FLOAT), 0,
793: CVFL, U(FLOAT,LONG), 0,
794: LDFD, U(FLOAT,DOUBLE),0,
795: CVDF, U(DOUBLE,FLOAT),0,
796: NEGF, FLOAT, 0,
797: NIL, 0, 0};
798:
799: interleave()
800: {
801: register struct node *p, *p1;
802:
803: register struct intleavetab *t;
804: register int r;
805: int count;
806: for (p= first.forw; p!=0; p = p->forw){
807: count = 0;
808: for (t =intltab; t->op != NIL; t++){
809: if (t->op == p->op && t->subop == p->subop){
810: count = t->intleavect;
811: break;
812: }
813: }
814: if (count < 1) continue;
815: p1 = p->forw;
816: clearuse();
817: clearreg();
818: while ((p1 != 0) && (p1->op != CBR) &&
819: (p1->subop == FLOAT || p1->subop == DOUBLE ||
820: ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
821: ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
822: {
823: if (((r = isreg(p1->code)) >= 0)){
824: uses[r] = p1;
825: if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) ||
826: ((p->subop&0xF)==DOUBLE))
827: uses[r+1] = p1;
828: }
829: else checkreg(p1,p1->code);
830: p1 = p1->forw;
831:
832: }
833: if (p1 == 0) return;
834: if (!(sideeffect(p, p1)))
835: insertblk(p,p1);
836: }
837:
838: }
839:
840:
841: insertblk(p, p1)
842: struct node *p, *p1;
843: {
844: p1->back->forw = p1->forw;
845: p1->forw->back = p1->back;
846: p1->forw = p->forw;
847: p->forw->back = p1;
848: p->forw = p1;
849: p1->back = p;
850: }
851:
852: OpCode termop[] = {
853: JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
854: CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
855: MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
856: LCOMM, COMM, NIL
857: };
858:
859: sideeffect(p,p1)
860: struct node *p, *p1;
861: {
862: register struct node *q;
863: register int r;
864: register OpCode *t;
865: register char *cp;
866: int i;
867:
868: if (p1->op == NIL) return(1); /* special instructions */
869:
870: for (t = termop; *t!=NIL; t++){
871: if (*t == p1->op) return(1);
872: }
873: if ((p1->forw != NULL) && (p1->forw->op == CBR))
874: return(1);
875: splitrand(p1);
876: r = isreg(lastrand);
877: if (uses[r] && r >= 0 ) return(1);
878: if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
879: (uses[r])) return(1);
880:
881: for (q = p1->back ; q!=p; q=q->back)
882: {
883: if ((p1->op == PUSH || p1->op == PUSHA) &&
884: (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))
885: return(1); /* keep args in order */
886: if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/
887: (strcmp(q->code+i-5,"-(sp)") == 0 )) ||
888: (strcmp(lastrand,"-(sp)") == 0)) return(1);
889: if (equstr(q->code, lastrand))
890: return(1);
891: if (q->op == STF || q->op == CVFL || q->op == CVLF)
892: {
893: if (equstr(q->code, regs[RT1])) return(1);
894: if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
895: if (equstr(q->code, regs[RT2]))
896: return(1);
897: /* handle the case std -56(fp) pushl -60(fp) pushl
898: -56(fp);
899: */
900: if ((p1->forw != NULL) && (q->op == STF) &&
901: (q->subop == DOUBLE)){
902: if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
903: return(1);
904: }
905: }
906: }
907: return(0);
908: }
909: checkreg(p,s)
910: struct node *p;
911: char *s;
912: {
913: char *cp2;
914: register int r;
915: /* check for (r),[r] */
916: do if (*s=='(' || *s=='[') {/* get register number */
917: char t;
918: cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
919: if ((r=isreg(cp2)) >= 0) {
920: uses[r]=p;
921: }
922: *s=t;
923: } while (*++s);
924: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.