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