home *** CD-ROM | disk | FTP | other *** search
- #
- /*
- * C object code improver
- */
-
- #include "c2h.c"
-
- struct optab optab[] {
- "jbr", JBR,
- "jeq", CBR | JEQ<<8,
- "jne", CBR | JNE<<8,
- "jle", CBR | JLE<<8,
- "jge", CBR | JGE<<8,
- "jlt", CBR | JLT<<8,
- "jgt", CBR | JGT<<8,
- "jlo", CBR | JLO<<8,
- "jhi", CBR | JHI<<8,
- "jlos", CBR | JLOS<<8,
- "jhis", CBR | JHIS<<8,
- "jmp", JMP,
- ".globl",EROU,
- "mov", MOV,
- "clr", CLR,
- "com", COM,
- "inc", INC,
- "dec", DEC,
- "neg", NEG,
- "tst", TST,
- "asr", ASR,
- "asl", ASL,
- "sxt", SXT,
- "cmp", CMP,
- "add", ADD,
- "sub", SUB,
- "bit", BIT,
- "bic", BIC,
- "bis", BIS,
- "mul", MUL,
- "ash", ASH,
- "xor", XOR,
- ".text",TEXT,
- ".data",DATA,
- ".bss", BSS,
- ".even",EVEN,
- "movf", MOVF,
- "movof",MOVOF,
- "movfo",MOVFO,
- "addf", ADDF,
- "subf", SUBF,
- "divf", DIVF,
- "mulf", MULF,
- "clrf", CLRF,
- "cmpf", CMPF,
- "negf", NEGF,
- "tstf", TSTF,
- "cfcc", CFCC,
- "sob", SOB,
- "jsr", JSR,
- ".end", END,
- 0, 0};
-
- char revbr[] { JNE, JEQ, JGT, JLT, JGE, JLE, JHIS, JLOS, JHI, JLO };
- int isn 20000;
-
- main(argc, argv)
- char **argv;
- {
- register int niter, maxiter, isend;
- extern end;
- extern fin, fout;
- int nflag;
-
- if (argc>1 && argv[1][0]=='+') {
- argc--;
- argv++;
- debug++;
- }
- if (argc>1 && argv[1][0]=='-') {
- argc--;
- argv++;
- nflag++;
- }
- if (argc>1) {
- if ((fin = open(argv[1], 0)) < 0) {
- printf("C2: can't find %s\n", argv[1]);
- exit(1);
- }
- } else
- fin = dup(0);
- if (argc>2) {
- if ((fout = creat(argv[2], 0666)) < 0) {
- fout = 1;
- printf("C2: can't create %s\n", argv[2]);
- exit(1);
- }
- } else
- fout = dup(1);
- lasta = firstr = lastr = sbrk(2);
- maxiter = 0;
- opsetup();
- do {
- isend = input();
- movedat();
- niter = 0;
- do {
- refcount();
- do {
- iterate();
- clearreg();
- niter++;
- } while (nchange);
- comjump();
- rmove();
- } while (nchange || jumpsw());
- addsob();
- output();
- if (niter > maxiter)
- maxiter = niter;
- lasta = firstr;
- } while (isend);
- flush();
- fout = 2;
- if (nflag) {
- printf("%d iterations\n", maxiter);
- printf("%d jumps to jumps\n", nbrbr);
- printf("%d inst. after jumps\n", iaftbr);
- printf("%d jumps to .+2\n", njp1);
- printf("%d redundant labels\n", nrlab);
- printf("%d cross-jumps\n", nxjump);
- printf("%d code motions\n", ncmot);
- printf("%d branches reversed\n", nrevbr);
- printf("%d redundant moves\n", redunm);
- printf("%d simplified addresses\n", nsaddr);
- printf("%d loops inverted\n", loopiv);
- printf("%d redundant jumps\n", nredunj);
- printf("%d common seqs before jmp's\n", ncomj);
- printf("%d skips over jumps\n", nskip);
- printf("%d sob's added\n", nsob);
- printf("%d redundant tst's\n", nrtst);
- printf("%d literals eliminated\n", nlit);
- printf("%dK core\n", ((lastr+01777)>>10)&077);
- flush();
- }
- exit(0);
- }
-
- input()
- {
- register struct node *p, *lastp;
- register int op;
-
- lastp = &first;
- for (;;) {
- op = getline();
- switch (op.op) {
-
- case LABEL:
- p = alloc(sizeof first);
- if (line[0] == 'L') {
- p->combop = LABEL;
- p->labno = getnum(line+1);
- p->code = 0;
- } else {
- p->combop = DLABEL;
- p->labno = 0;
- p->code = copy(line);
- }
- break;
-
- case JBR:
- case CBR:
- case JMP:
- case JSW:
- p = alloc(sizeof first);
- p->combop = op;
- if (*curlp=='L' && (p->labno = getnum(curlp+1)))
- p->code = 0;
- else {
- p->labno = 0;
- p->code = copy(curlp);
- }
- break;
-
- default:
- p = alloc(sizeof first);
- p->combop = op;
- p->labno = 0;
- p->code = copy(curlp);
- break;
-
- }
- p->forw = 0;
- p->back = lastp;
- lastp->forw = p;
- lastp = p;
- p->ref = 0;
- if (op==EROU)
- return(1);
- if (op==END)
- return(0);
- }
- }
-
- getline()
- {
- register char *lp;
- register c;
-
- lp = line;
- while (c = getchar()) {
- if (c==':') {
- *lp++ = 0;
- return(LABEL);
- }
- if (c=='\n') {
- *lp++ = 0;
- return(oplook());
- }
- *lp++ = c;
- }
- *lp++ = 0;
- return(END);
- }
-
- getnum(ap)
- char *ap;
- {
- register char *p;
- register n, c;
-
- p = ap;
- n = 0;
- while ((c = *p++) >= '0' && c <= '9')
- n = n*10 + c - '0';
- if (*--p != 0)
- return(0);
- return(n);
- }
-
- output()
- {
- register struct node *t;
- register struct optab *op;
- register int byte;
-
- t = &first;
- while (t = t->forw) switch (t->op) {
-
- case END:
- return;
-
- case LABEL:
- printf("L%d:", t->labno);
- continue;
-
- case DLABEL:
- printf("%s:", t->code);
- continue;
-
- default:
- if ((byte = t->subop) == BYTE)
- t->subop = 0;
- for (op = optab; op->opstring!=0; op++)
- if (op->opcode == t->combop) {
- printf("%s", op->opstring);
- if (byte==BYTE)
- printf("b");
- break;
- }
- if (t->code) {
- reducelit(t);
- printf("\t%s\n", t->code);
- } else if (t->op==JBR || t->op==CBR)
- printf("\tL%d\n", t->labno);
- else
- printf("\n");
- continue;
-
- case JSW:
- printf("L%d\n", t->labno);
- continue;
-
- case SOB:
- printf("sob %s,L%d\n", t->code, t->labno);
- continue;
-
- case 0:
- if (t->code)
- printf("%s", t->code);
- printf("\n");
- continue;
- }
- }
-
- /*
- * Notice addresses of the form
- * $xx,xx(r)
- * and replace them with (pc),xx(r)
- * -- Thanx and a tip of the Hatlo hat to Bliss-11.
- */
- reducelit(at)
- struct node *at;
- {
- register char *c1, *c2;
- char *c2s;
- register struct node *t;
-
- t = at;
- if (*t->code != '$')
- return;
- c1 = t->code;
- while (*c1 != ',')
- if (*c1++ == '\0')
- return;
- c2s = c1;
- c1++;
- if (*c1=='*')
- c1++;
- c2 = t->code+1;
- while (*c1++ == *c2++);
- if (*--c1!='(' || *--c2!=',')
- return;
- t->code = copy("(pc)", c2s);
- nlit++;
- }
-
- copy(ap)
- char *ap;
- {
- register char *p, *np;
- char *onp;
- register n;
- int na;
-
- na = nargs();
- p = ap;
- n = 0;
- if (*p==0)
- return(0);
- do
- n++;
- while (*p++);
- if (na>1) {
- p = (&ap)[1];
- while (*p++)
- n++;
- }
- onp = np = alloc(n);
- p = ap;
- while (*np++ = *p++);
- if (na>1) {
- p = (&ap)[1];
- np--;
- while (*np++ = *p++);
- }
- return(onp);
- }
-
- opsetup()
- {
- register struct optab *optp, **ophp;
- register char *p;
-
- for (optp = optab; p = optp->opstring; optp++) {
- ophp = &ophash[(((p[0]<<3)+(p[1]<<1)+p[2])&077777) % OPHS];
- while (*ophp++)
- if (ophp > &ophash[OPHS])
- ophp = ophash;
- *--ophp = optp;
- }
- }
-
- oplook()
- {
- register struct optab *optp;
- register char *lp, *op;
- static char tmpop[32];
- struct optab **ophp;
-
- op = tmpop;
- for (lp = line; *lp && *lp!=' ' && *lp!='\t';)
- *op++ = *lp++;
- *op++ = 0;
- while (*lp=='\t' || *lp==' ')
- lp++;
- curlp = lp;
- ophp = &ophash[(((tmpop[0]<<3)+(tmpop[1]<<1)+tmpop[2])&077777) % OPHS];
- while (optp = *ophp) {
- op = optp->opstring;
- lp = tmpop;
- while (*lp == *op++)
- if (*lp++ == 0)
- return(optp->opcode);
- if (*lp++=='b' && *lp++==0 && *--op==0)
- return(optp->opcode + (BYTE<<8));
- ophp++;
- if (ophp >= &ophash[OPHS])
- ophp = ophash;
- }
- if (line[0]=='L') {
- lp = &line[1];
- while (*lp)
- if (*lp<'0' || *lp++>'9')
- return(0);
- curlp = line;
- return(JSW);
- }
- curlp = line;
- return(0);
- }
-
- refcount()
- {
- register struct node *p, *lp;
- static struct node *labhash[LABHS];
- register struct node **hp;
-
- for (hp = labhash; hp < &labhash[LABHS];)
- *hp++ = 0;
- for (p = first.forw; p!=0; p = p->forw)
- if (p->op==LABEL) {
- labhash[p->labno % LABHS] = p;
- p->refc = 0;
- }
- for (p = first.forw; p!=0; p = p->forw) {
- if (p->op==JBR || p->op==CBR || p->op==JSW) {
- p->ref = 0;
- lp = labhash[p->labno % LABHS];
- if (lp==0 || p->labno!=lp->labno)
- for (lp = first.forw; lp!=0; lp = lp->forw) {
- if (lp->op==LABEL && p->labno==lp->labno)
- break;
- }
- if (lp) {
- hp = nonlab(lp)->back;
- if (hp!=lp) {
- p->labno = hp->labno;
- lp = hp;
- }
- p->ref = lp;
- lp->refc++;
- }
- }
- }
- for (p = first.forw; p!=0; p = p->forw)
- if (p->op==LABEL && p->refc==0
- && (lp = nonlab(p))->op && lp->op!=JSW)
- decref(p);
- }
-
- iterate()
- {
- register struct node *p, *rp, *p1;
-
- nchange = 0;
- for (p = first.forw; p!=0; p = p->forw) {
- if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) {
- rp = nonlab(p->ref);
- if (rp->op==JBR && rp->labno && p!=rp) {
- nbrbr++;
- p->labno = rp->labno;
- decref(p->ref);
- rp->ref->refc++;
- p->ref = rp->ref;
- nchange++;
- }
- }
- if (p->op==CBR && (p1 = p->forw)->op==JBR) {
- rp = p->ref;
- do
- rp = rp->back;
- while (rp->op==LABEL);
- if (rp==p1) {
- decref(p->ref);
- p->ref = p1->ref;
- p->labno = p1->labno;
- p1->forw->back = p;
- p->forw = p1->forw;
- p->subop = revbr[p->subop];
- nchange++;
- nskip++;
- }
- }
- if (p->op==JBR || p->op==JMP) {
- while (p->forw && p->forw->op!=LABEL
- && p->forw->op!=EROU && p->forw->op!=END) {
- nchange++;
- iaftbr++;
- if (p->forw->ref)
- decref(p->forw->ref);
- p->forw = p->forw->forw;
- p->forw->back = p;
- }
- rp = p->forw;
- while (rp && rp->op==LABEL) {
- if (p->ref == rp) {
- p->back->forw = p->forw;
- p->forw->back = p->back;
- p = p->back;
- decref(rp);
- nchange++;
- njp1++;
- break;
- }
- rp = rp->forw;
- }
- xjump(p);
- p = codemove(p);
- }
- }
- }
-
- xjump(ap)
- {
- register int *p1, *p2, *p3;
- int nxj;
-
- nxj = 0;
- p1 = ap;
- if ((p2 = p1->ref)==0)
- return(0);
- for (;;) {
- while ((p1 = p1->back) && p1->op==LABEL);
- while ((p2 = p2->back) && p2->op==LABEL);
- if (!equop(p1, p2) || p1==p2)
- return(nxj);
- p3 = insertl(p2);
- p1->combop = JBR;
- p1->ref = p3;
- p1->labno = p3->labno;
- p1->code = 0;
- nxj++;
- nxjump++;
- nchange++;
- }
- }
-
- insertl(ap)
- struct node *ap;
- {
- register struct node *lp, *op;
-
- op = ap;
- if (op->op == LABEL) {
- op->refc++;
- return(op);
- }
- if (op->back->op == LABEL) {
- op = op->back;
- op->refc++;
- return(op);
- }
- lp = alloc(sizeof first);
- lp->combop = LABEL;
- lp->labno = isn++;
- lp->ref = 0;
- lp->code = 0;
- lp->refc = 1;
- lp->back = op->back;
- lp->forw = op;
- op->back->forw = lp;
- op->back = lp;
- return(lp);
- }
-
- codemove(ap)
- struct node *ap;
- {
- register struct node *p1, *p2, *p3;
- struct node *t, *tl;
- int n;
-
- p1 = ap;
- if (p1->op!=JBR || (p2 = p1->ref)==0)
- return(p1);
- while (p2->op == LABEL)
- if ((p2 = p2->back) == 0)
- return(p1);
- if (p2->op!=JBR && p2->op!=JMP)
- goto ivloop;
- p2 = p2->forw;
- p3 = p1->ref;
- while (p3) {
- if (p3->op==JBR || p3->op==JMP) {
- if (p1==p3)
- return(p1);
- ncmot++;
- nchange++;
- p1->back->forw = p2;
- p1->forw->back = p3;
- p2->back->forw = p3->forw;
- p3->forw->back = p2->back;
- p2->back = p1->back;
- p3->forw = p1->forw;
- decref(p1->ref);
- return(p2);
- } else
- p3 = p3->forw;
- }
- return(p1);
- ivloop:
- if (p1->forw->op!=LABEL)
- return(p1);
- p3 = p2 = p2->forw;
- n = 16;
- do {
- if ((p3 = p3->forw) == 0 || p3==p1 || --n==0)
- return(p1);
- } while (p3->op!=CBR || p3->labno!=p1->forw->labno);
- do
- if ((p1 = p1->back) == 0)
- return(ap);
- while (p1!=p3);
- p1 = ap;
- tl = insertl(p1);
- p3->subop = revbr[p3->subop];
- decref(p3->ref);
- p2->back->forw = p1;
- p3->forw->back = p1;
- p1->back->forw = p2;
- p1->forw->back = p3;
- t = p1->back;
- p1->back = p2->back;
- p2->back = t;
- t = p1->forw;
- p1->forw = p3->forw;
- p3->forw = t;
- p2 = insertl(p1->forw);
- p3->labno = p2->labno;
- p3->ref = p2;
- decref(tl);
- if (tl->refc<=0)
- nrlab--;
- loopiv++;
- nchange++;
- return(p3);
- }
-
- comjump()
- {
- register struct node *p1, *p2, *p3;
-
- for (p1 = first.forw; p1!=0; p1 = p1->forw)
- if (p1->op==JBR && (p2 = p1->ref) && p2->refc > 1)
- for (p3 = p1->forw; p3!=0; p3 = p3->forw)
- if (p3->op==JBR && p3->ref == p2)
- backjmp(p1, p3);
- }
-
- backjmp(ap1, ap2)
- struct node *ap1, *ap2;
- {
- register struct node *p1, *p2, *p3;
-
- p1 = ap1;
- p2 = ap2;
- for(;;) {
- while ((p1 = p1->back) && p1->op==LABEL);
- p2 = p2->back;
- if (equop(p1, p2)) {
- p3 = insertl(p1);
- p2->back->forw = p2->forw;
- p2->forw->back = p2->back;
- p2 = p2->forw;
- decref(p2->ref);
- p2->labno = p3->labno;
- p2->ref = p3;
- nchange++;
- ncomj++;
- } else
- return;
- }
- }
-