|
|
1.1 root 1: #
2: /*
3: * C object code improver-- second part
4: */
5:
6: #include "c2.h"
7:
8: rmove()
9: {
10: register struct node *p;
11: register int r;
12: register r1, flt;
13:
14: for (p=first.forw; p!=0; p = p->forw) {
15: flt = 0;
16: switch (p->op) {
17:
18: case MOVF:
19: case MOVFO:
20: case MOVOF:
21: flt = NREG;
22:
23: case MOV:
24: if (p->subop==BYTE)
25: goto dble;
26: dualop(p);
27: if ((r = findrand(regs[RT1], flt)) >= 0) {
28: if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR
29: && p->forw->op!=SXT
30: && p->forw->op!=CFCC) {
31: p->forw->back = p->back;
32: p->back->forw = p->forw;
33: redunm++;
34: continue;
35: }
36: }
37: if (equstr(regs[RT1], "$0")) {
38: p->op = CLR;
39: strcpy(regs[RT1], regs[RT2]);
40: regs[RT2][0] = 0;
41: p->code = copy(1, regs[RT1]);
42: goto sngl;
43: }
44: repladdr(p, 0, flt);
45: r = isreg(regs[RT1]);
46: r1 = isreg(regs[RT2]);
47: dest(regs[RT2], flt);
48: if (r >= 0)
49: if (r1 >= 0)
50: savereg(r1+flt, regs[r+flt]);
51: else
52: savereg(r+flt, regs[RT2]);
53: else
54: if (r1 >= 0)
55: savereg(r1+flt, regs[RT1]);
56: else
57: setcon(regs[RT1], regs[RT2]);
58: source(regs[RT1]);
59: setcc(regs[RT2]);
60: continue;
61:
62: case ADDF:
63: case SUBF:
64: case DIVF:
65: case MULF:
66: flt = NREG;
67: goto dble;
68:
69: case ADD:
70: case SUB:
71: case BIC:
72: case BIS:
73: case MUL:
74: case DIV:
75: case ASH:
76: dble:
77: dualop(p);
78: if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) {
79: p->op = CLR;
80: strcpy(regs[RT1], regs[RT2]);
81: regs[RT2][0] = 0;
82: p->code = copy(1, regs[RT1]);
83: goto sngl;
84: }
85: if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) {
86: if (p->forw->op!=CBR) {
87: p->back->forw = p->forw;
88: p->forw->back = p->back;
89: continue;
90: }
91: }
92: repladdr(p, 0, flt);
93: source(regs[RT1]);
94: dest(regs[RT2], flt);
95: if (p->op==DIV && (r = isreg(regs[RT2])>=0))
96: regs[r+1][0] = 0;
97: ccloc[0] = 0;
98: continue;
99:
100: case CLRF:
101: case NEGF:
102: flt = NREG;
103:
104: case CLR:
105: case COM:
106: case INC:
107: case DEC:
108: case NEG:
109: case ASR:
110: case ASL:
111: case SXT:
112: singop(p);
113: sngl:
114: dest(regs[RT1], flt);
115: if (p->op==CLR && flt==0)
116: if ((r = isreg(regs[RT1])) >= 0)
117: savereg(r, "$0");
118: else
119: setcon("$0", regs[RT1]);
120: ccloc[0] = 0;
121: continue;
122:
123: case TSTF:
124: flt = NREG;
125:
126: case TST:
127: singop(p);
128: repladdr(p, 0, flt);
129: source(regs[RT1]);
130: if (equstr(regs[RT1], ccloc)) {
131: p->back->forw = p->forw;
132: p->forw->back = p->back;
133: p = p->back;
134: nrtst++;
135: nchange++;
136: }
137: continue;
138:
139: case CMPF:
140: flt = NREG;
141:
142: case CMP:
143: case BIT:
144: dualop(p);
145: source(regs[RT1]);
146: source(regs[RT2]);
147: if(p->op==BIT) {
148: if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) {
149: p->op = TST;
150: strcpy(regs[RT1], regs[RT2]);
151: regs[RT2][0] = 0;
152: p->code = copy(1, regs[RT1]);
153: nchange++;
154: nsaddr++;
155: } else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) {
156: p->op = TST;
157: regs[RT2][0] = 0;
158: p->code = copy(1, regs[RT1]);
159: nchange++;
160: nsaddr++;
161: }
162: if (equstr(regs[RT1], "$0")) {
163: p->op = TST;
164: regs[RT2][0] = 0;
165: p->code = copy(1, regs[RT1]);
166: nchange++;
167: nsaddr++;
168: } else if (equstr(regs[RT2], "$0")) {
169: p->op = TST;
170: strcpy(regs[RT1], regs[RT2]);
171: regs[RT2][0] = 0;
172: p->code = copy(1, regs[RT1]);
173: nchange++;
174: nsaddr++;
175: }
176: }
177: repladdr(p, 1, flt);
178: ccloc[0] = 0;
179: continue;
180:
181: case CBR:
182: r = -1;
183: if (p->back->op==TST || p->back->op==CMP) {
184: if (p->back->op==TST) {
185: singop(p->back);
186: savereg(RT2, "$0");
187: } else
188: dualop(p->back);
189: if (equstr(regs[RT1], regs[RT2])
190: && natural(regs[RT1]) && natural(regs[RT2]))
191: r = compare(p->subop, "$1", "$1");
192: else
193: r = compare(p->subop, findcon(RT1), findcon(RT2));
194: if (r==0) {
195: if (p->forw->op==CBR
196: || p->forw->op==SXT
197: || p->forw->op==CFCC) {
198: p->back->forw = p->forw;
199: p->forw->back = p->back;
200: } else {
201: p->back->back->forw = p->forw;
202: p->forw->back = p->back->back;
203: }
204: decref(p->ref);
205: p = p->back->back;
206: nchange++;
207: } else if (r>0) {
208: p->op = JBR;
209: p->subop = 0;
210: p->back->back->forw = p;
211: p->back = p->back->back;
212: p = p->back;
213: nchange++;
214: }
215: }
216: case CFCC:
217: ccloc[0] = 0;
218: continue;
219:
220: case JBR:
221: redunbr(p);
222:
223: default:
224: clearreg();
225: }
226: }
227: }
228:
229: jumpsw()
230: {
231: register struct node *p, *p1;
232: register t;
233: register struct node *tp;
234: int nj;
235:
236: t = 0;
237: nj = 0;
238: for (p=first.forw; p!=0; p = p->forw)
239: p->refc = ++t;
240: for (p=first.forw; p!=0; p = p1) {
241: p1 = p->forw;
242: if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
243: && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) {
244: if (p->ref==p1->ref)
245: continue;
246: p->subop = revbr[p->subop];
247: tp = p1->ref;
248: p1->ref = p->ref;
249: p->ref = tp;
250: t = p1->labno;
251: p1->labno = p->labno;
252: p->labno = t;
253: nrevbr++;
254: nj++;
255: }
256: }
257: return(nj);
258: }
259:
260: addsob()
261: {
262: register struct node *p, *p1;
263:
264: for (p = &first; (p1 = p->forw)!=0; p = p1) {
265: if (p->op==DEC && isreg(p->code)>=0
266: && p1->op==CBR && p1->subop==JNE) {
267: if (p->refc < p1->ref->refc)
268: continue;
269: if (toofar(p1))
270: continue;
271: p->labno = p1->labno;
272: p->op = SOB;
273: p->subop = 0;
274: p1->forw->back = p;
275: p->forw = p1->forw;
276: nsob++;
277: }
278: }
279: }
280:
281: toofar(p)
282: struct node *p;
283: {
284: register struct node *p1;
285: int len;
286:
287: len = 0;
288: for (p1 = p->ref; p1 && p1!=p; p1 = p1->forw)
289: len += ilen(p1);
290: if (len < 128)
291: return(0);
292: return(1);
293: }
294:
295: ilen(p)
296: register struct node *p;
297: {
298:
299: switch (p->op) {
300: case LABEL:
301: case DLABEL:
302: case TEXT:
303: case EROU:
304: case EVEN:
305: return(0);
306:
307: case CBR:
308: return(6);
309:
310: default:
311: dualop(p);
312: return(2 + adrlen(regs[RT1]) + adrlen(regs[RT2]));
313: }
314: }
315:
316: adrlen(s)
317: register char *s;
318: {
319: if (*s == 0)
320: return(0);
321: if (*s=='r')
322: return(0);
323: if (*s=='(' && *(s+1)=='r')
324: return(0);
325: if (*s=='-' && *(s+1)=='(')
326: return(0);
327: return(2);
328: }
329:
330: abs(x)
331: {
332: return(x<0? -x: x);
333: }
334:
335: equop(ap1, p2)
336: struct node *ap1, *p2;
337: {
338: register char *cp1, *cp2;
339: register struct node *p1;
340:
341: p1 = ap1;
342: if (p1->op!=p2->op || p1->subop!=p2->subop)
343: return(0);
344: if (p1->op>0 && p1->op<MOV)
345: return(0);
346: cp1 = p1->code;
347: cp2 = p2->code;
348: if (cp1==0 && cp2==0)
349: return(1);
350: if (cp1==0 || cp2==0)
351: return(0);
352: while (*cp1 == *cp2++)
353: if (*cp1++ == 0)
354: return(1);
355: return(0);
356: }
357:
358: decref(p)
359: register struct node *p;
360: {
361: if (--p->refc <= 0) {
362: nrlab++;
363: p->back->forw = p->forw;
364: p->forw->back = p->back;
365: }
366: }
367:
368: struct node *
369: nonlab(p)
370: struct node *p;
371: {
372: CHECK(10);
373: while (p && p->op==LABEL)
374: p = p->forw;
375: return(p);
376: }
377:
378: char *
379: alloc(n)
380: register n;
381: {
382: register char *p;
383:
384: #define round(a,b) ((((a)+(b)-1)/(b))*(b))
385: n=round(n,sizeof(char *));
386: if (alasta+n < alastr) {
387: p = alasta;
388: alasta += n;
389: return(p);
390: }
391: if (lasta+n >= lastr) {
392: if (sbrk(2000) == (char *)-1) {
393: fprintf(stderr, "C Optimizer: out of space\n");
394: exit(1);
395: }
396: lastr += 2000;
397: }
398: p = lasta;
399: lasta += n;
400: return(p);
401: }
402:
403: clearreg()
404: {
405: register int i;
406:
407: for (i=0; i<2*NREG; i++)
408: regs[i][0] = '\0';
409: conloc[0] = 0;
410: ccloc[0] = 0;
411: }
412:
413: savereg(ai, as)
414: char *as;
415: {
416: register char *p, *s, *sp;
417:
418: sp = p = regs[ai];
419: s = as;
420: if (source(s))
421: return;
422: while (*p++ = *s) {
423: if (s[0]=='(' && s[1]=='r' && s[2]<'5') {
424: *sp = 0;
425: return;
426: }
427: if (*s++ == ',')
428: break;
429: }
430: *--p = '\0';
431: }
432:
433: dest(as, flt)
434: char *as;
435: {
436: register char *s;
437: register int i;
438:
439: s = as;
440: source(s);
441: if ((i = isreg(s)) >= 0)
442: regs[i+flt][0] = 0;
443: for (i=0; i<NREG+NREG; i++)
444: if (*regs[i]=='*' && equstr(s, regs[i]+1))
445: regs[i][0] = 0;
446: if (equstr(s, conloc))
447: conloc[0] = '\0';
448: while ((i = findrand(s, flt)) >= 0)
449: regs[i][0] = 0;
450: while (*s) {
451: if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') {
452: for (i=0; i<NREG+NREG; i++) {
453: if (regs[i][0] != '$')
454: regs[i][0] = 0;
455: conloc[0] = 0;
456: }
457: return;
458: }
459: }
460: }
461:
462: singop(ap)
463: struct node *ap;
464: {
465: register char *p1, *p2;
466:
467: p1 = ap->code;
468: p2 = regs[RT1];
469: while (*p2++ = *p1++);
470: regs[RT2][0] = 0;
471: }
472:
473:
474: dualop(ap)
475: struct node *ap;
476: {
477: register char *p1, *p2;
478: register struct node *p;
479:
480: p = ap;
481: p1 = p->code;
482: p2 = regs[RT1];
483: while (*p1 && *p1!=',')
484: *p2++ = *p1++;
485: *p2++ = 0;
486: p2 = regs[RT2];
487: *p2 = 0;
488: if (*p1++ !=',')
489: return;
490: while (*p1==' ' || *p1=='\t')
491: p1++;
492: while (*p2++ = *p1++)
493: ;
494: }
495:
496: findrand(as, flt)
497: char *as;
498: {
499: register int i;
500: for (i = flt; i<NREG+flt; i++) {
501: if (equstr(regs[i], as))
502: return(i);
503: }
504: return(-1);
505: }
506:
507: isreg(as)
508: char *as;
509: {
510: register char *s;
511:
512: s = as;
513: if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0)
514: return(s[1]-'0');
515: return(-1);
516: }
517:
518: check()
519: {
520: register struct node *p, *lp;
521: register count;
522:
523: lp = &first;
524: count = 0;
525: for (p=first.forw; p!=0; p = p->forw) {
526: if (++count > 10000)
527: abort(0);
528: if (p->back != lp)
529: abort(1);
530: lp = p;
531: }
532: }
533:
534: source(ap)
535: char *ap;
536: {
537: register char *p1, *p2;
538:
539: p1 = ap;
540: p2 = p1;
541: if (*p1==0)
542: return(0);
543: while (*p2++);
544: if (*p1=='-' && *(p1+1)=='('
545: || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='('
546: || *(p2-2)=='+') {
547: while (*p1 && *p1++!='r');
548: if (*p1>='0' && *p1<='4')
549: regs[*p1 - '0'][0] = 0;
550: return(1);
551: }
552: return(0);
553: }
554:
555: repladdr(p, f, flt)
556: struct node *p;
557: {
558: register r;
559: int r1;
560: register char *p1, *p2;
561: static char rt1[50], rt2[50];
562:
563: if (f)
564: r1 = findrand(regs[RT2], flt);
565: else
566: r1 = -1;
567: r = findrand(regs[RT1], flt);
568: if (r1 >= NREG)
569: r1 -= NREG;
570: if (r >= NREG)
571: r -= NREG;
572: if (r>=0 || r1>=0) {
573: p2 = regs[RT1];
574: for (p1 = rt1; *p1++ = *p2++;);
575: if (regs[RT2][0]) {
576: p1 = rt2;
577: *p1++ = ',';
578: for (p2 = regs[RT2]; *p1++ = *p2++;);
579: } else
580: rt2[0] = 0;
581: if (r>=0) {
582: rt1[0] = 'r';
583: rt1[1] = r + '0';
584: rt1[2] = 0;
585: nsaddr++;
586: }
587: if (r1>=0) {
588: rt2[1] = 'r';
589: rt2[2] = r1 + '0';
590: rt2[3] = 0;
591: nsaddr++;
592: }
593: p->code = copy(2, rt1, rt2);
594: }
595: }
596:
597: movedat()
598: {
599: register struct node *p1, *p2;
600: struct node *p3;
601: register seg;
602: struct node data;
603: struct node *datp;
604:
605: if (first.forw == 0)
606: return;
607: if (lastseg != TEXT && lastseg != -1) {
608: p1 = (struct node *)alloc(sizeof(first));
609: p1->op = lastseg;
610: p1->subop = 0;
611: p1->code = NULL;
612: p1->forw = first.forw;
613: p1->back = &first;
614: first.forw->back = p1;
615: first.forw = p1;
616: }
617: datp = &data;
618: for (p1 = first.forw; p1!=0; p1 = p1->forw) {
619: if (p1->op == DATA) {
620: p2 = p1->forw;
621: while (p2 && p2->op!=TEXT)
622: p2 = p2->forw;
623: if (p2==0)
624: break;
625: p3 = p1->back;
626: p1->back->forw = p2->forw;
627: p2->forw->back = p3;
628: p2->forw = 0;
629: datp->forw = p1;
630: p1->back = datp;
631: p1 = p3;
632: datp = p2;
633: }
634: }
635: if (data.forw) {
636: datp->forw = first.forw;
637: first.forw->back = datp;
638: data.forw->back = &first;
639: first.forw = data.forw;
640: }
641: seg = lastseg;
642: for (p1 = first.forw; p1!=0; p1 = p1->forw) {
643: if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) {
644: if (p2 = p1->forw) {
645: if (p2->op==TEXT||p2->op==DATA||p2->op==BSS)
646: p1->op = p2->op;
647: }
648: if (p1->op == seg || p1->forw&&p1->forw->op==seg) {
649: p1->back->forw = p1->forw;
650: p1->forw->back = p1->back;
651: p1 = p1->back;
652: continue;
653: }
654: seg = p1->op;
655: }
656: }
657: }
658:
659: redunbr(p)
660: register struct node *p;
661: {
662: register struct node *p1;
663: register char *ap1;
664: char *ap2;
665:
666: if ((p1 = p->ref) == 0)
667: return;
668: p1 = nonlab(p1);
669: if (p1->op==TST) {
670: singop(p1);
671: savereg(RT2, "$0");
672: } else if (p1->op==CMP)
673: dualop(p1);
674: else
675: return;
676: if (p1->forw->op!=CBR)
677: return;
678: ap1 = findcon(RT1);
679: ap2 = findcon(RT2);
680: p1 = p1->forw;
681: if (compare(p1->subop, ap1, ap2)>0) {
682: nredunj++;
683: nchange++;
684: decref(p->ref);
685: p->ref = p1->ref;
686: p->labno = p1->labno;
687: p->ref->refc++;
688: }
689: }
690:
691: char *
692: findcon(i)
693: {
694: register char *p;
695: register r;
696:
697: p = regs[i];
698: if (*p=='$')
699: return(p);
700: if ((r = isreg(p)) >= 0)
701: return(regs[r]);
702: if (equstr(p, conloc))
703: return(conval);
704: return(p);
705: }
706:
707: compare(oper, cp1, cp2)
708: register char *cp1, *cp2;
709: {
710: register unsigned n1, n2;
711:
712: if (*cp1++ != '$' || *cp2++ != '$')
713: return(-1);
714: n1 = 0;
715: while (*cp2 >= '0' && *cp2 <= '7') {
716: n1 <<= 3;
717: n1 += *cp2++ - '0';
718: }
719: n2 = n1;
720: n1 = 0;
721: while (*cp1 >= '0' && *cp1 <= '7') {
722: n1 <<= 3;
723: n1 += *cp1++ - '0';
724: }
725: if (*cp1=='+')
726: cp1++;
727: if (*cp2=='+')
728: cp2++;
729: do {
730: if (*cp1++ != *cp2)
731: return(-1);
732: } while (*cp2++);
733: switch(oper) {
734:
735: case JEQ:
736: return(n1 == n2);
737: case JNE:
738: return(n1 != n2);
739: case JLE:
740: return((int)n1 <= (int)n2);
741: case JGE:
742: return((int)n1 >= (int)n2);
743: case JLT:
744: return((int)n1 < (int)n2);
745: case JGT:
746: return((int)n1 > (int)n2);
747: case JLO:
748: return(n1 < n2);
749: case JHI:
750: return(n1 > n2);
751: case JLOS:
752: return(n1 <= n2);
753: case JHIS:
754: return(n1 >= n2);
755: }
756: return(-1);
757: }
758:
759: setcon(ar1, ar2)
760: char *ar1, *ar2;
761: {
762: register char *cl, *cv, *p;
763:
764: cl = ar2;
765: cv = ar1;
766: if (*cv != '$')
767: return;
768: if (!natural(cl))
769: return;
770: p = conloc;
771: while (*p++ = *cl++);
772: p = conval;
773: while (*p++ = *cv++);
774: }
775:
776: equstr(ap1, ap2)
777: char *ap1, *ap2;
778: {
779: char *p1, *p2;
780:
781: p1 = ap1;
782: p2 = ap2;
783: do {
784: if (*p1++ != *p2)
785: return(0);
786: } while (*p2++);
787: return(1);
788: }
789:
790: setcc(ap)
791: char *ap;
792: {
793: register char *p, *p1;
794:
795: p = ap;
796: if (!natural(p)) {
797: ccloc[0] = 0;
798: return;
799: }
800: p1 = ccloc;
801: while (*p1++ = *p++);
802: }
803:
804: natural(ap)
805: char *ap;
806: {
807: register char *p;
808:
809: p = ap;
810: if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(')
811: return(0);
812: while (*p++);
813: p--;
814: if (*--p == '+' || *p ==')' && *--p != '5')
815: return(0);
816: return(1);
817: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.