|
|
1.1 root 1: /*
2: * C object code improver
3: */
4:
5: #include "c2.h"
6:
7: struct optab optab[] = {
8: "jbr", JBR,
9: "jeq", CBR | JEQ<<8,
10: "jne", CBR | JNE<<8,
11: "jle", CBR | JLE<<8,
12: "jge", CBR | JGE<<8,
13: "jlt", CBR | JLT<<8,
14: "jgt", CBR | JGT<<8,
15: "jlo", CBR | JLO<<8,
16: "jhi", CBR | JHI<<8,
17: "jlos", CBR | JLOS<<8,
18: "jhis", CBR | JHIS<<8,
19: "jmp", JMP,
20: ".globl",EROU,
21: "mov", MOV,
22: "clr", CLR,
23: "com", COM,
24: "inc", INC,
25: "dec", DEC,
26: "neg", NEG,
27: "tst", TST,
28: "asr", ASR,
29: "asl", ASL,
30: "sxt", SXT,
31: "cmp", CMP,
32: "add", ADD,
33: "sub", SUB,
34: "bit", BIT,
35: "bic", BIC,
36: "bis", BIS,
37: "mul", MUL,
38: "ash", ASH,
39: "xor", XOR,
40: ".text",TEXT,
41: ".data",DATA,
42: ".bss", BSS,
43: ".even",EVEN,
44: "movf", MOVF,
45: "movof",MOVOF,
46: "movfo",MOVFO,
47: "addf", ADDF,
48: "subf", SUBF,
49: "divf", DIVF,
50: "mulf", MULF,
51: "clrf", CLRF,
52: "cmpf", CMPF,
53: "negf", NEGF,
54: "tstf", TSTF,
55: "cfcc", CFCC,
56: "sob", SOB,
57: "jsr", JSR,
58: ".end", END,
59: 0, 0};
60:
61: char revbr[] = { JNE, JEQ, JGT, JLT, JGE, JLE, JHIS, JLOS, JHI, JLO };
62: int isn = 20000;
63: int lastseg = -1;
64:
65: #define NSTK 5000
66:
67: main(argc, argv)
68: char **argv;
69: {
70: register int niter, maxiter, isend;
71: extern end;
72: int nflag;
73: char stspace[NSTK];
74:
75: if (argc>1 && argv[1][0]=='+') {
76: argc--;
77: argv++;
78: debug++;
79: }
80: nflag = 0;
81: if (argc>1 && argv[1][0]=='-') {
82: argc--;
83: argv++;
84: nflag++;
85: }
86: if (argc>1) {
87: if (freopen(argv[1], "r", stdin) == NULL) {
88: fprintf(stderr, "C2: can't find %s\n", argv[1]);
89: exit(1);
90: }
91: }
92: if (argc>2) {
93: if (freopen(argv[2], "w", stdout) == NULL) {
94: fprintf(stderr, "C2: can't create %s\n", argv[2]);
95: exit(1);
96: }
97: }
98: lasta = firstr = lastr = sbrk(sizeof(char *));
99: maxiter = 0;
100: opsetup();
101: do {
102: alasta = stspace;
103: alastr = &stspace[NSTK];
104: isend = input();
105: movedat();
106: niter = 0;
107: do {
108: refcount();
109: do {
110: iterate();
111: clearreg();
112: niter++;
113: } while (nchange);
114: comjump();
115: rmove();
116: } while (nchange || jumpsw());
117: addsob();
118: output();
119: if (niter > maxiter)
120: maxiter = niter;
121: lasta = firstr;
122: } while (isend);
123: if (nflag) {
124: fprintf(stderr, "%d iterations\n", maxiter);
125: fprintf(stderr, "%d jumps to jumps\n", nbrbr);
126: fprintf(stderr, "%d inst. after jumps\n", iaftbr);
127: fprintf(stderr, "%d jumps to .+2\n", njp1);
128: fprintf(stderr, "%d redundant labels\n", nrlab);
129: fprintf(stderr, "%d cross-jumps\n", nxjump);
130: fprintf(stderr, "%d code motions\n", ncmot);
131: fprintf(stderr, "%d branches reversed\n", nrevbr);
132: fprintf(stderr, "%d redundant moves\n", redunm);
133: fprintf(stderr, "%d simplified addresses\n", nsaddr);
134: fprintf(stderr, "%d loops inverted\n", loopiv);
135: fprintf(stderr, "%d redundant jumps\n", nredunj);
136: fprintf(stderr, "%d common seqs before jmp's\n", ncomj);
137: fprintf(stderr, "%d skips over jumps\n", nskip);
138: fprintf(stderr, "%d sob's added\n", nsob);
139: fprintf(stderr, "%d redundant tst's\n", nrtst);
140: fprintf(stderr, "%d literals eliminated\n", nlit);
141: fprintf(stderr, "%dK core\n", (((int)lastr+01777)>>10)&077);
142: }
143: exit(0);
144: }
145:
146: input()
147: {
148: register struct node *p, *lastp;
149: register int oper;
150:
151: lastp = &first;
152: for (;;) {
153: oper = getline();
154: switch (oper&0377) {
155:
156: case LABEL:
157: p = (struct node *)alloc(sizeof first);
158: if (line[0] == 'L') {
159: p->op = LABEL;
160: p->subop = 0;
161: p->labno = getnum(line+1);
162: p->code = 0;
163: } else {
164: p->op = DLABEL;
165: p->subop = 0;
166: p->labno = 0;
167: p->code = copy(1, line);
168: }
169: break;
170:
171: case JBR:
172: case CBR:
173: case JMP:
174: case JSW:
175: p = (struct node *)alloc(sizeof first);
176: p->op = oper&0377;
177: p->subop = oper>>8;
178: if (*curlp=='L' && (p->labno = getnum(curlp+1)))
179: p->code = 0;
180: else {
181: p->labno = 0;
182: p->code = copy(1, curlp);
183: }
184: break;
185:
186: default:
187: p = (struct node *)alloc(sizeof first);
188: p->op = oper&0377;
189: p->subop = oper>>8;
190: p->labno = 0;
191: p->code = copy(1, curlp);
192: break;
193:
194: }
195: p->forw = 0;
196: p->back = lastp;
197: lastp->forw = p;
198: lastp = p;
199: p->ref = 0;
200: if (oper==EROU)
201: return(1);
202: if (oper==END)
203: return(0);
204: }
205: }
206:
207: getline()
208: {
209: register char *lp;
210: register c;
211:
212: lp = line;
213: while ((c = getchar())==' ' || c=='\t')
214: ;
215: do {
216: if (c==':') {
217: *lp++ = 0;
218: return(LABEL);
219: }
220: if (c=='\n') {
221: *lp++ = 0;
222: return(oplook());
223: }
224: if (lp >= &line[LSIZE-2]) {
225: fprintf(stderr, "C2: Sorry, input line too long\n");
226: exit(1);
227: }
228: *lp++ = c;
229: } while ((c = getchar()) != EOF);
230: *lp++ = 0;
231: return(END);
232: }
233:
234: getnum(ap)
235: char *ap;
236: {
237: register char *p;
238: register n, c;
239:
240: p = ap;
241: n = 0;
242: while ((c = *p++) >= '0' && c <= '9')
243: n = n*10 + c - '0';
244: if (*--p != 0)
245: return(0);
246: return(n);
247: }
248:
249: output()
250: {
251: register struct node *t;
252: register struct optab *oper;
253: register int byte;
254:
255: t = &first;
256: while (t = t->forw) switch (t->op) {
257:
258: case END:
259: return;
260:
261: case LABEL:
262: printf("L%d:", t->labno);
263: continue;
264:
265: case DLABEL:
266: printf("%s:", t->code);
267: continue;
268:
269: case TEXT:
270: case DATA:
271: case BSS:
272: lastseg = t->op;
273:
274: default:
275: if ((byte = t->subop) == BYTE)
276: t->subop = 0;
277: for (oper = optab; oper->opstring!=0; oper++)
278: if ((oper->opcode&0377) == t->op
279: && (oper->opcode>>8) == t->subop) {
280: printf("%s", oper->opstring);
281: if (byte==BYTE)
282: printf("b");
283: break;
284: }
285: if (t->code) {
286: reducelit(t);
287: printf("\t%s\n", t->code);
288: } else if (t->op==JBR || t->op==CBR)
289: printf("\tL%d\n", t->labno);
290: else
291: printf("\n");
292: continue;
293:
294: case JSW:
295: printf("L%d\n", t->labno);
296: continue;
297:
298: case SOB:
299: printf("sob %s", t->code);
300: if (t->labno)
301: printf(",L%d", t->labno);
302: printf("\n");
303: continue;
304:
305: case 0:
306: if (t->code)
307: printf("%s", t->code);
308: printf("\n");
309: continue;
310: }
311: }
312:
313: /*
314: * Notice addresses of the form
315: * $xx,xx(r)
316: * and replace them with (pc),xx(r)
317: * -- Thanx and a tip of the Hatlo hat to Bliss-11.
318: */
319: reducelit(at)
320: struct node *at;
321: {
322: register char *c1, *c2;
323: char *c2s;
324: register struct node *t;
325:
326: t = at;
327: if (*t->code != '$')
328: return;
329: c1 = t->code;
330: while (*c1 != ',')
331: if (*c1++ == '\0')
332: return;
333: c2s = c1;
334: c1++;
335: if (*c1=='*')
336: c1++;
337: c2 = t->code+1;
338: while (*c1++ == *c2++);
339: if (*--c1!='(' || *--c2!=',')
340: return;
341: t->code = copy(2, "(pc)", c2s);
342: nlit++;
343: }
344:
345: char *
346: copy(na, ap)
347: char *ap;
348: {
349: register char *p, *np;
350: char *onp;
351: register n;
352:
353: p = ap;
354: n = 0;
355: if (*p==0)
356: return(0);
357: do
358: n++;
359: while (*p++);
360: if (na>1) {
361: p = (&ap)[1];
362: while (*p++)
363: n++;
364: }
365: onp = np = alloc(n);
366: p = ap;
367: while (*np++ = *p++)
368: ;
369: if (na>1) {
370: p = (&ap)[1];
371: np--;
372: while (*np++ = *p++);
373: }
374: return(onp);
375: }
376:
377: opsetup()
378: {
379: register struct optab *optp, **ophp;
380: register char *p;
381:
382: for (optp = optab; p = optp->opstring; optp++) {
383: ophp = &ophash[(((p[0]<<3)+(p[1]<<1)+p[2])&077777) % OPHS];
384: while (*ophp++)
385: if (ophp > &ophash[OPHS])
386: ophp = ophash;
387: *--ophp = optp;
388: }
389: }
390:
391: oplook()
392: {
393: register struct optab *optp;
394: register char *lp, *np;
395: static char tmpop[32];
396: struct optab **ophp;
397:
398: if (line[0]=='\0') {
399: curlp = line;
400: return(0);
401: }
402: np = tmpop;
403: for (lp = line; *lp && *lp!=' ' && *lp!='\t';)
404: *np++ = *lp++;
405: *np++ = 0;
406: while (*lp=='\t' || *lp==' ')
407: lp++;
408: curlp = lp;
409: ophp = &ophash[(((tmpop[0]<<3)+(tmpop[1]<<1)+tmpop[2])&077777) % OPHS];
410: while (optp = *ophp) {
411: np = optp->opstring;
412: lp = tmpop;
413: while (*lp == *np++)
414: if (*lp++ == 0)
415: return(optp->opcode);
416: if (*lp++=='b' && *lp++==0 && *--np==0)
417: return(optp->opcode + (BYTE<<8));
418: ophp++;
419: if (ophp >= &ophash[OPHS])
420: ophp = ophash;
421: }
422: if (line[0]=='L') {
423: lp = &line[1];
424: while (*lp)
425: if (*lp<'0' || *lp++>'9')
426: return(0);
427: curlp = line;
428: return(JSW);
429: }
430: curlp = line;
431: return(0);
432: }
433:
434: refcount()
435: {
436: register struct node *p, *lp;
437: static struct node *labhash[LABHS];
438: register struct node **hp, *tp;
439:
440: for (hp = labhash; hp < &labhash[LABHS];)
441: *hp++ = 0;
442: for (p = first.forw; p!=0; p = p->forw)
443: if (p->op==LABEL) {
444: labhash[p->labno % LABHS] = p;
445: p->refc = 0;
446: }
447: for (p = first.forw; p!=0; p = p->forw) {
448: if (p->op==JBR || p->op==CBR || p->op==JSW) {
449: p->ref = 0;
450: lp = labhash[p->labno % LABHS];
451: if (lp==0 || p->labno!=lp->labno)
452: for (lp = first.forw; lp!=0; lp = lp->forw) {
453: if (lp->op==LABEL && p->labno==lp->labno)
454: break;
455: }
456: if (lp) {
457: tp = nonlab(lp)->back;
458: if (tp!=lp) {
459: p->labno = tp->labno;
460: lp = tp;
461: }
462: p->ref = lp;
463: lp->refc++;
464: }
465: }
466: }
467: for (p = first.forw; p!=0; p = p->forw)
468: if (p->op==LABEL && p->refc==0
469: && (lp = nonlab(p))->op && lp->op!=JSW)
470: decref(p);
471: }
472:
473: iterate()
474: {
475: register struct node *p, *rp, *p1;
476:
477: nchange = 0;
478: for (p = first.forw; p!=0; p = p->forw) {
479: CHECK(0);
480: if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) {
481: rp = nonlab(p->ref);
482: if (rp->op==JBR && rp->labno && p->labno!=rp->labno) {
483: nbrbr++;
484: p->labno = rp->labno;
485: decref(p->ref);
486: rp->ref->refc++;
487: p->ref = rp->ref;
488: CHECK(1);
489: nchange++;
490: }
491: }
492: if (p->op==CBR && (p1 = p->forw)->op==JBR) {
493: rp = p->ref;
494: do
495: rp = rp->back;
496: while (rp->op==LABEL);
497: if (rp==p1) {
498: decref(p->ref);
499: p->ref = p1->ref;
500: p->labno = p1->labno;
501: p1->forw->back = p;
502: p->forw = p1->forw;
503: p->subop = revbr[p->subop];
504: nchange++;
505: CHECK(2);
506: nskip++;
507: }
508: }
509: if (p->op==JBR || p->op==JMP) {
510: while (p->forw && p->forw->op!=LABEL
511: && p->forw->op!=DLABEL
512: && p->forw->op!=EROU && p->forw->op!=END
513: && p->forw->op!=0 && p->forw->op!=DATA) {
514: nchange++;
515: iaftbr++;
516: if (p->forw->ref)
517: decref(p->forw->ref);
518: p->forw = p->forw->forw;
519: p->forw->back = p;
520: CHECK(3);
521: }
522: rp = p->forw;
523: while (rp && rp->op==LABEL) {
524: if (p->ref == rp) {
525: p->back->forw = p->forw;
526: p->forw->back = p->back;
527: p = p->back;
528: decref(rp);
529: nchange++;
530: CHECK(4);
531: njp1++;
532: break;
533: }
534: rp = rp->forw;
535: }
536: }
537: if (p->op==JBR || p->op==JMP) {
538: xjump(p);
539: p = codemove(p);
540: }
541: }
542: }
543:
544: xjump(p1)
545: register struct node *p1;
546: {
547: register struct node *p2, *p3;
548:
549: if ((p2 = p1->ref)==0)
550: return;
551: for (;;) {
552: while ((p1 = p1->back) && p1->op==LABEL);
553: while ((p2 = p2->back) && p2->op==LABEL);
554: if (!equop(p1, p2) || p1==p2)
555: return;
556: p3 = insertl(p2);
557: p1->op = JBR;
558: p1->subop = 0;
559: p1->ref = p3;
560: p1->labno = p3->labno;
561: p1->code = 0;
562: nxjump++;
563: CHECK(5);
564: nchange++;
565: }
566: }
567:
568: struct node *
569: insertl(oldp)
570: register struct node *oldp;
571: {
572: register struct node *lp;
573:
574: if (oldp->op == LABEL) {
575: oldp->refc++;
576: return(oldp);
577: }
578: if (oldp->back->op == LABEL) {
579: oldp = oldp->back;
580: oldp->refc++;
581: return(oldp);
582: }
583: lp = (struct node *)alloc(sizeof first);
584: lp->op = LABEL;
585: lp->subop = 0;
586: lp->labno = isn++;
587: lp->ref = 0;
588: lp->code = 0;
589: lp->refc = 1;
590: lp->back = oldp->back;
591: lp->forw = oldp;
592: oldp->back->forw = lp;
593: oldp->back = lp;
594: CHECK(6);
595: return(lp);
596: }
597:
598: struct node *
599: codemove(p)
600: struct node *p;
601: {
602: register struct node *p1, *p2, *p3;
603: struct node *t, *tl;
604: int n;
605:
606: p1 = p;
607: if (p1->op!=JBR || (p2 = p1->ref)==0)
608: return(p1);
609: while (p2->op == LABEL)
610: if ((p2 = p2->back) == 0)
611: return(p1);
612: if (p2->op!=JBR && p2->op!=JMP)
613: goto ivloop;
614: if (p1==p2)
615: return(p1);
616: p2 = p2->forw;
617: p3 = p1->ref;
618: while (p3) {
619: if (p3->op==JBR || p3->op==JMP) {
620: if (p1==p3 || p1->forw==p3 || p1->back==p3)
621: return(p1);
622: ncmot++;
623: nchange++;
624: CHECK(70);
625: p1->back->forw = p2;
626: p1->forw->back = p3;
627: p2->back->forw = p3->forw;
628: p3->forw->back = p2->back;
629: p2->back = p1->back;
630: p3->forw = p1->forw;
631: decref(p1->ref);
632: CHECK(7);
633: return(p2);
634: } else
635: p3 = p3->forw;
636: }
637: return(p1);
638: ivloop:
639: if (p1->forw->op!=LABEL)
640: return(p1);
641: p3 = p2 = p2->forw;
642: n = 16;
643: do {
644: if ((p3 = p3->forw) == 0 || p3==p1 || --n==0)
645: return(p1);
646: } while (p3->op!=CBR || p3->labno!=p1->forw->labno);
647: do
648: if ((p1 = p1->back) == 0)
649: return(p);
650: while (p1!=p3);
651: p1 = p;
652: tl = insertl(p1);
653: p3->subop = revbr[p3->subop];
654: decref(p3->ref);
655: p2->back->forw = p1;
656: p3->forw->back = p1;
657: p1->back->forw = p2;
658: p1->forw->back = p3;
659: t = p1->back;
660: p1->back = p2->back;
661: p2->back = t;
662: t = p1->forw;
663: p1->forw = p3->forw;
664: p3->forw = t;
665: p2 = insertl(p1->forw);
666: p3->labno = p2->labno;
667: p3->ref = p2;
668: decref(tl);
669: if (tl->refc<=0)
670: nrlab--;
671: loopiv++;
672: nchange++;
673: CHECK(8);
674: return(p3);
675: }
676:
677: comjump()
678: {
679: register struct node *p1, *p2, *p3;
680:
681: for (p1 = first.forw; p1!=0; p1 = p1->forw)
682: if (p1->op==JBR && (p2 = p1->ref) && p2->refc > 1)
683: for (p3 = p1->forw; p3!=0; p3 = p3->forw)
684: if (p3->op==JBR && p3->ref == p2)
685: backjmp(p1, p3);
686: }
687:
688: backjmp(ap1, ap2)
689: struct node *ap1, *ap2;
690: {
691: register struct node *p1, *p2, *p3;
692:
693: p1 = ap1;
694: p2 = ap2;
695: for(;;) {
696: while ((p1 = p1->back) && p1->op==LABEL);
697: p2 = p2->back;
698: if (equop(p1, p2)) {
699: p3 = insertl(p1);
700: p2->back->forw = p2->forw;
701: p2->forw->back = p2->back;
702: p2 = p2->forw;
703: decref(p2->ref);
704: p2->labno = p3->labno;
705: p2->ref = p3;
706: nchange++;
707: ncomj++;
708: CHECK(9);
709: } else
710: return;
711: }
712: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.