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