|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "%W% (Berkeley/CCI) %G%";
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, 1);
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 && ord(p1->op) < ord(MOV))
335: return(0);
336: if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
337: cp1 = p1->code;
338: cp2 = p2->code;
339: if (cp1==0 && cp2==0)
340: return(1);
341: if (cp1==0 || cp2==0)
342: return(0);
343: while (*cp1 == *cp2++)
344: if (*cp1++ == 0)
345: return(1);
346: return(0);
347: }
348:
349: delnode(p) register struct node *p; {
350: p->back->forw = p->forw;
351: p->forw->back = p->back;
352: }
353:
354: decref(p)
355: register struct node *p;
356: {
357: if (p && --p->refc <= 0) {
358: nrlab++; nchange++;
359: delnode(p);
360: }
361: }
362:
363: struct node *
364: nonlab(ap)
365: struct node *ap;
366: {
367: register struct node *p;
368:
369: p = ap;
370: while (p && p->op==LABEL)
371: p = p->forw;
372: return(p);
373: }
374:
375: clearuse() {
376: register struct node **i;
377: register short *p;
378: for (i=uses+NREG; i>uses;) *--i=0;
379: useacc = 0;
380: for (p=usecnt+NUSE; p>usecnt;) *--p=0;
381: }
382:
383: clearreg() {
384: register char **i;
385: for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; }
386: conloc[0] = 0; ccloc[0] = 0;
387: }
388:
389: savereg(ai, s, type)
390: register char *s;
391: {
392: register char *p, *sp;
393:
394: sp = p = regs[ai];
395: /* if any indexing, must be parameter or local */
396: /* indirection (as in "*-4(fp)") is ok, however */
397: *p++ = type;
398: if (*s=='*' || *s=='$')
399: *p++ = *s++;
400: if (natural(s))
401: strcpy(p, s);
402: else {*sp = 0; return;}
403: }
404:
405: dest(s,type, ccflg)
406: register char *s;
407: {
408: register int i;
409:
410: if ((i = isreg(s)) >= 0) {
411: *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
412: if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD)
413: *(short *)(regs[i+1]) = 0;
414: }
415: for (i=NREG; --i>=0;)
416: if (regs[i][1]=='*' && equstr(s, regs[i]+2))
417: *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
418: while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
419: *(short *)(regs[i]) = 0;
420:
421: if (!natural(s)) {/* wild store, everything except constants vanishes */
422: for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
423: conloc[0] = 0; ccloc[0] = 0;
424: } else {
425: if(ccflg)setcc(s,type); /* natural destinations set condition codes */
426: if (equstr(s, conloc))
427: conloc[0] = 0;
428: }
429: }
430:
431: splitrand(p) struct node *p; {
432: /* separate operands at commas, set up 'regs' and 'lastrand' */
433: register char *p1, *p2; register char **preg;
434:
435: preg=regs+RT1;
436: if (p1=p->code) while (*p1) {
437: lastrand=p2= *preg++;
438: while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
439: *p2=0;
440: }
441: while (preg<(regs+RT1+5)) *(*preg++)=0;
442: }
443:
444: compat(have, want)
445: register int have, want;
446: {
447: register int hsrc, hdst;
448: extern int bitsize[];
449:
450: if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
451: hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
452: if (want>=QUAD)
453: return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]);
454: return(hsrc==want && hdst>=want && hdst<QUAD);
455: }
456:
457: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
458:
459: findrand(as, type)
460: char *as;
461: {
462: register char **i;
463: for (i = regs+NREG; --i>=regs;) {
464: if (**i && equstr(*i+1, as) && compat(**i,type))
465: return(i-regs);
466: }
467: return(-1);
468: }
469:
470: isreg(s)
471: register char *s;
472: {
473: if (*s++!='r' || !isdigit(*s++)) return(-1);
474: if (*s==0) return(*--s-'0');
475: if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
476: return(-1);
477: }
478:
479: /*
480: check()
481: {
482: register struct node *p, *lp;
483:
484: lp = &first;
485: for (p=first.forw; p!=0; p = p->forw) {
486: if (p->back != lp)
487: abort(-1);
488: lp = p;
489: }
490: }
491: */
492:
493: newcode(p) struct node *p; {
494: register char *p1,*p2,**preg;
495:
496: preg=regs+RT1; p2=line;
497: while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
498: *--p2=0;
499: p->code=copy(line);
500: }
501:
502: repladdr(p)
503: struct node *p;
504: {
505: register int r;
506: register char *p1;
507: register char **preg;
508: register int nrepl;
509:
510: preg=regs+RT1; nrepl=0;
511: while (lastrand!=(p1= *preg++))
512: if (0<=(r=findrand(p1,p->subop))) {
513: *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
514: nchange++; nrepl++; nsaddr++;
515: }
516: if (nrepl) newcode(p);
517: }
518:
519: /* conditional branches which are never/always taken */
520: reduncbr(p)
521: register struct node *p;
522: {
523: register struct node *p1;
524: register char *ap1, *ap2;
525:
526: p1 = p->back;
527: if (p1->op==CMP) {
528: splitrand(p1);
529: ap1 = findcon(regs[RT1], p1->subop);
530: ap2 = findcon(regs[RT2], p1->subop);
531: } else {
532: if(!ccloc[0])
533: return;
534: ap1 = findcon(ccloc+1, ccloc[0]);
535: ap2 = "$0";
536: }
537: switch (compare(p->subop, ap1, ap2)) {
538: case 0: /* branch never taken */
539: delnode(p);
540: nredunj++;
541: nchange++;
542: decref(p->ref);
543: if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
544: delnode(p1);
545: nrtst++;
546: }
547: break;
548: case 1: /* branch always taken */
549: p->op = JBR;
550: p->subop = 0;
551: p->pop = 0;
552: nchange++;
553: if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) {
554: delnode(p1);
555: nrtst++;
556: }
557: }
558: }
559:
560: /* a jump to a redundant compare (start of a 'for') */
561: redunbr(p)
562: register struct node *p;
563: {
564: register struct node *p1;
565: register char *ap1, *ap2;
566:
567: if ((p1 = p->ref) == 0)
568: return;
569: p1 = nonlab(p1);
570: if (p1->op==TST || p1->op==CMP)
571: splitrand(p1);
572: else
573: return;
574: if (p1->forw->op==CBR) {
575: ap1 = findcon(regs[RT1], p1->subop);
576: if (p1->op==TST)
577: ap2 = "$0";
578: else
579: ap2 = findcon(regs[RT2], p1->subop);
580: p1 = p1->forw;
581: if (compare(p1->subop, ap1, ap2) > 0) {
582: nredunj++;
583: nchange++;
584: decref(p->ref);
585: p->ref = p1->ref;
586: p->labno = p1->labno;
587: #ifdef COPYCODE
588: if (p->labno == 0)
589: p->code = p1->code;
590: if (p->ref)
591: #endif
592: p->ref->refc++;
593: }
594: } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
595: equtype(ccloc[0],p1->subop)) {
596: p1=insertl(p1->forw); decref(p->ref); p->ref=p1;
597: nrtst++; nchange++;
598: }
599: }
600:
601: char *
602: findcon(p, type)
603: register char *p;
604: {
605: register int r;
606:
607: if (*p=='$')
608: return(p);
609: if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
610: return(regs[r]+1);
611: if (equstr(p, conloc) && equtype(conloc[0], type))
612: return(conval+1);
613: return(p);
614: }
615:
616: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
617: compare(op, acp1, acp2)
618: char *acp1, *acp2;
619: {
620: register char *cp1, *cp2;
621: register int n1, n2, sign;
622:
623: cp1 = acp1;
624: cp2 = acp2;
625: if (*cp1++ != '$' || *cp2++ != '$')
626: return(-1);
627: n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
628: while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
629: n1 *= sign;
630: n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
631: while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
632: n2 *= sign;
633: if (*cp1=='+')
634: cp1++;
635: if (*cp2=='+')
636: cp2++;
637: do {
638: if (*cp1++ != *cp2)
639: return(-1);
640: } while (*cp2++);
641: switch(op) {
642:
643: case JEQ:
644: return(n1 == n2);
645: case JNE:
646: return(n1 != n2);
647: case JLE:
648: return(n1 <= n2);
649: case JGE:
650: return(n1 >= n2);
651: case JLT:
652: return(n1 < n2);
653: case JGT:
654: return(n1 > n2);
655: case JLO:
656: return((unsigned)n1 < (unsigned)n2);
657: case JHI:
658: return((unsigned)n1 > (unsigned)n2);
659: case JLOS:
660: return((unsigned)n1 <= (unsigned)n2);
661: case JHIS:
662: return((unsigned)n1 >= (unsigned)n2);
663: }
664: return(-1);
665: }
666:
667: setcon(cv, cl, type)
668: register char *cv, *cl;
669: {
670: register char *p;
671:
672: if (*cv != '$')
673: return;
674: if (!natural(cl))
675: return;
676: p = conloc;
677: while (*p++ = *cl++);
678: p = conval;
679: *p++ = type;
680: while (*p++ = *cv++);
681: }
682:
683: setcc(ap,type)
684: char *ap;
685: {
686: register char *p, *p1;
687:
688: p = ap;
689: if (!natural(p)) {
690: ccloc[0] = 0;
691: return;
692: }
693: p1 = ccloc;
694: *p1++ = type;
695: while (*p1++ = *p++);
696: }
697:
698: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
699: while (*p) if (*p++=='[') return(1);
700: return(0);
701: }
702:
703: natural(p)
704: register char *p;
705: {/* 1->simple local, parameter, global, or register; 0->otherwise */
706:
707: if (*p=='*' || *p=='(' || *p=='$')
708: return(0);
709: while (*p++);
710: p--;
711: if (*--p==']' || *p==')' &&
712: !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
713: return(0);
714: return(1);
715: }
716:
717: /*
718: ** Tell if an argument is most likely static.
719: */
720:
721: isstatic(cp)
722: register char *cp;
723: {
724: if (*cp == '_' || *cp == 'L')
725: return (1);
726: return (0);
727: }
728:
729:
730: checkaobdisp(p)
731: register struct node *p;
732: {
733: register struct node *q;
734: register int i;
735:
736:
737: if (!aobflag) return(1);
738: /* backward search */
739: i = 0;
740: q = p;
741: while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
742: {
743: if (p->ref == q)
744: return(1);
745: }
746:
747: /* forward search */
748: i = 0;
749: q = p;
750: while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
751: {
752: if (p->ref == q)
753: return(1);
754: }
755: return(0);
756: }
757:
758:
759: struct intleavetab intltab[] = {
760: ADDF, FLOAT, 1,
761: ADDF, DOUBLE, 1,
762: SUBF, FLOAT, 1,
763: SUBF, DOUBLE, 1,
764: MULF, FLOAT, 1,
765: MULF, DOUBLE, 1,
766: DIVF, FLOAT, 1,
767: DIVF, DOUBLE, 1,
768: SINF, FLOAT, 1,
769: COSF, FLOAT, 1,
770: ATANF, FLOAT, 1,
771: LOGF, FLOAT, 1,
772: SQRTF, FLOAT, 1,
773: EXPF, FLOAT, 1,
774: LDF, FLOAT, 0,
775: LDF, DOUBLE, 0,
776: LNF, FLOAT, 0,
777: LNF, DOUBLE, 0,
778: STF, FLOAT, 0,
779: CMPF, FLOAT, 0,
780: CMPF, DOUBLE, 0,
781: CMPF2, FLOAT, 0,
782: TSTF, FLOAT, 0,
783: TSTF, DOUBLE, 0,
784: PUSHD, DOUBLE, 0,
785: CVLF, U(LONG,FLOAT), 0,
786: CVFL, U(FLOAT,LONG), 0,
787: LDFD, U(FLOAT,DOUBLE),0,
788: CVDF, U(DOUBLE,FLOAT),0,
789: NEGF, FLOAT, 0,
790: NIL, 0, 0};
791:
792: interleave()
793: {
794: register struct node *p, *p1;
795:
796: register struct intleavetab *t;
797: register int r;
798: int count;
799: for (p= first.forw; p!=0; p = p->forw){
800: count = 0;
801: for (t =intltab; t->op != NIL; t++){
802: if (t->op == p->op && t->subop == p->subop){
803: count = t->intleavect;
804: break;
805: }
806: }
807: if (count < 1) continue;
808: p1 = p->forw;
809: clearuse();
810: clearreg();
811: while ((p1 != 0) && (p1->op != CBR) &&
812: (p1->subop == FLOAT || p1->subop == DOUBLE ||
813: ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
814: ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
815: {
816: if (((r = isreg(p1->code)) >= 0)){
817: uses[r] = p1;
818: if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) ||
819: ((p->subop&0xF)==DOUBLE))
820: uses[r+1] = p1;
821: }
822: else checkreg(p1,p1->code);
823: p1 = p1->forw;
824:
825: }
826: if (p1 == 0) return;
827: if (!(sideeffect(p, p1)))
828: insertblk(p,p1);
829: }
830:
831: }
832:
833:
834: insertblk(p, p1)
835: struct node *p, *p1;
836: {
837: p1->back->forw = p1->forw;
838: p1->forw->back = p1->back;
839: p1->forw = p->forw;
840: p->forw->back = p1;
841: p->forw = p1;
842: p1->back = p;
843: }
844:
845: OpCode termop[] = {
846: JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
847: CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
848: MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
849: LCOMM, COMM, NIL
850: };
851:
852: sideeffect(p,p1)
853: struct node *p, *p1;
854: {
855: register struct node *q;
856: register int r;
857: register OpCode *t;
858: register char *cp;
859: int i;
860:
861: if (p1->op == NIL) return(1); /* special instructions */
862:
863: for (t = termop; *t!=NIL; t++){
864: if (*t == p1->op) return(1);
865: }
866: if ((p1->forw != NULL) && (p1->forw->op == CBR))
867: return(1);
868: splitrand(p1);
869: r = isreg(lastrand);
870: if (uses[r] && r >= 0 ) return(1);
871: if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
872: (uses[r])) return(1);
873:
874: for (q = p1->back ; q!=p; q=q->back)
875: {
876: if ((p1->op == PUSH || p1->op == PUSHA) &&
877: (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))
878: return(1); /* keep args in order */
879: if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/
880: (strcmp(q->code+i-5,"-(sp)") == 0 )) ||
881: (strcmp(lastrand,"-(sp)") == 0)) return(1);
882: if (equstr(q->code, lastrand))
883: return(1);
884: if (q->op == STF || q->op == CVFL || q->op == CVLF)
885: {
886: if (equstr(q->code, regs[RT1])) return(1);
887: if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
888: if (equstr(q->code, regs[RT2]))
889: return(1);
890: /* handle the case std -56(fp) pushl -60(fp) pushl
891: -56(fp);
892: */
893: if ((p1->forw != NULL) && (q->op == STF) &&
894: (q->subop == DOUBLE)){
895: if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
896: return(1);
897: }
898: }
899: }
900: return(0);
901: }
902: checkreg(p,s)
903: struct node *p;
904: char *s;
905: {
906: char *cp2;
907: register int r;
908: /* check for (r),[r] */
909: do if (*s=='(' || *s=='[') {/* get register number */
910: char t;
911: cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
912: if ((r=isreg(cp2)) >= 0) {
913: uses[r]=p;
914: }
915: *s=t;
916: } while (*++s);
917: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.