home *** CD-ROM | disk | FTP | other *** search
- #
- /*
- * C object code improver-- second part
- */
-
- #include "c2h.c"
-
- rmove()
- {
- register struct node *p;
- register char *cp;
- register int r;
- int r1, flt;
-
- for (p=first.forw; p!=0; p = p->forw) {
- if (debug) {
- for (r=0; r<2*NREG; r++)
- if (regs[r][0])
- printf("%d: %s\n", r, regs[r]);
- printf("-\n");
- }
- flt = 0;
- switch (p->op) {
-
- case MOVF:
- case MOVFO:
- case MOVOF:
- flt = NREG;
-
- case MOV:
- if (p->subop==BYTE)
- goto badmov;
- dualop(p);
- if ((r = findrand(regs[RT1], flt)) >= 0) {
- if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR) {
- p->forw->back = p->back;
- p->back->forw = p->forw;
- redunm++;
- continue;
- }
- }
- repladdr(p, 0, flt);
- r = isreg(regs[RT1]);
- r1 = isreg(regs[RT2]);
- dest(regs[RT2], flt);
- if (r >= 0)
- if (r1 >= 0)
- savereg(r1+flt, regs[r+flt]);
- else
- savereg(r+flt, regs[RT2]);
- else
- if (r1 >= 0)
- savereg(r1+flt, regs[RT1]);
- else
- setcon(regs[RT1], regs[RT2]);
- source(regs[RT1]);
- setcc(regs[RT2]);
- continue;
-
- case ADDF:
- case SUBF:
- case DIVF:
- case MULF:
- flt = NREG;
-
- case ADD:
- case SUB:
- case BIC:
- case BIS:
- case MUL:
- case DIV:
- case ASH:
- badmov:
- dualop(p);
- repladdr(p, 0, flt);
- source(regs[RT1]);
- dest(regs[RT2], flt);
- if (p->op==DIV && (r = isreg(regs[RT2])>=0))
- regs[r+1][0] = 0;
- ccloc[0] = 0;
- continue;
-
- case CLRF:
- case NEGF:
- flt = NREG;
-
- case CLR:
- case COM:
- case INC:
- case DEC:
- case NEG:
- case ASR:
- case ASL:
- case SXT:
- singop(p);
- dest(regs[RT1], flt);
- if (p->op==CLR && flt==0)
- if ((r = isreg(regs[RT1])) >= 0)
- savereg(r, "$0");
- else
- setcon("$0", regs[RT1]);
- setcc(regs[RT1]);
- continue;
-
- case TSTF:
- flt = NREG;
-
- case TST:
- singop(p);
- repladdr(p, 0, flt);
- source(regs[RT1]);
- if (equstr(regs[RT1], ccloc)) {
- p->back->forw = p->forw;
- p->forw->back = p->back;
- p = p->back;
- nrtst++;
- nchange++;
- }
- continue;
-
- case CMPF:
- flt = NREG;
-
- case CMP:
- case BIT:
- dualop(p);
- source(regs[RT1]);
- source(regs[RT2]);
- repladdr(p, 1, flt);
- ccloc[0] = 0;
- continue;
-
- case CBR:
- case CFCC:
- ccloc[0] = 0;
- continue;
-
- case JBR:
- redunbr(p);
-
- default:
- clearreg();
- }
- }
- }
-
- jumpsw()
- {
- register struct node *p, *p1;
- register t;
- int nj;
-
- t = 0;
- nj = 0;
- for (p=first.forw; p!=0; p = p->forw)
- p->refc = ++t;
- for (p=first.forw; p!=0; p = p1) {
- p1 = p->forw;
- if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
- && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) {
- p->subop = revbr[p->subop];
- t = p1->ref;
- p1->ref = p->ref;
- p->ref = t;
- t = p1->labno;
- p1->labno = p->labno;
- p->labno = t;
- nrevbr++;
- nj++;
- }
- }
- return(nj);
- }
-
- addsob()
- {
- register struct node *p, *p1;
-
- for (p = &first; (p1 = p->forw)!=0; p = p1) {
- if (p->op==DEC && isreg(p->code)>=0
- && p1->combop==(CBR|JNE<<8)) {
- if (p->refc < p1->ref->refc)
- continue;
- if (p->refc - p1->ref->refc > 50)
- continue;
- p->labno = p1->labno;
- p->combop = SOB;
- p1->forw->back = p;
- p->forw = p1->forw;
- nsob++;
- }
- }
- }
-
- abs(x)
- {
- return(x<0? -x: x);
- }
-
- equop(ap1, p2)
- struct node *ap1, *p2;
- {
- register char *cp1, *cp2;
- register struct node *p1;
-
- p1 = ap1;
- if (p1->combop != p2->combop)
- return(0);
- if (p1->op>0 && p1->op<MOV)
- return(0);
- cp1 = p1->code;
- cp2 = p2->code;
- if (cp1==0 && cp2==0)
- return(1);
- if (cp1==0 || cp2==0)
- return(0);
- while (*cp1 == *cp2++)
- if (*cp1++ == 0)
- return(1);
- return(0);
- }
-
- decref(ap)
- {
- register struct node *p;
-
- p = ap;
- if (--p->refc <= 0) {
- nrlab++;
- p->back->forw = p->forw;
- p->forw->back = p->back;
- }
- }
-
- nonlab(ap)
- struct node *ap;
- {
- register struct node *p;
-
- p = ap;
- while (p && p->op==LABEL)
- p = p->forw;
- return(p);
- }
-
- alloc(an)
- {
- register int n;
- register char *p;
-
- n = an;
- n++;
- n =& ~01;
- if (lasta+n >= lastr) {
- if (sbrk(2000) == -1) {
- write(2, "Optimizer: out of space\n", 14);
- exit(1);
- }
- lastr =+ 2000;
- }
- p = lasta;
- lasta =+ n;
- return(p);
- }
-
- clearreg()
- {
- register int i;
-
- for (i=0; i<2*NREG; i++)
- regs[i][0] = '\0';
- conloc[0] = 0;
- ccloc[0] = 0;
- }
-
- savereg(ai, as)
- char *as;
- {
- register char *p, *s, *sp;
-
- sp = p = regs[ai];
- s = as;
- if (source(s))
- return;
- while (*p++ = *s) {
- if (s[0]=='(' && s[1]=='r' && s[2]<'5') {
- *sp = 0;
- return;
- }
- if (*s++ == ',')
- break;
- }
- *--p = '\0';
- }
-
- dest(as, flt)
- char *as;
- {
- register char *s;
- register int i;
-
- s = as;
- if ((i = isreg(s)) >= 0)
- regs[i+flt][0] = 0;
- while ((i = findrand(s, flt)) >= 0)
- regs[i][0] = 0;
- while (*s) {
- if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') {
- for (i=flt; i<flt+NREG; i++) {
- if (regs[i][0] != '$')
- regs[i][0] = 0;
- conloc[0] = 0;
- }
- return;
- }
- }
- }
-
- singop(ap)
- struct node *ap;
- {
- register char *p1, *p2;
-
- p1 = ap->code;
- p2 = regs[RT1];
- while (*p2++ = *p1++);
- regs[RT2][0] = 0;
- }
-
-
- dualop(ap)
- struct node *ap;
- {
- register char *p1, *p2;
- register struct node *p;
-
- p = ap;
- p1 = p->code;
- p2 = regs[RT1];
- while (*p1 && *p1!=',')
- *p2++ = *p1++;
- *p2++ = 0;
- p2 = regs[RT2];
- *p2 = 0;
- if (*p1++ !=',')
- return;
- while (*p2++ = *p1++);
- }
-
- findrand(as, flt)
- char *as;
- {
- register int i;
- for (i = flt; i<NREG+flt; i++) {
- if (equstr(regs[i], as))
- return(i);
- }
- return(-1);
- }
-
- isreg(as)
- char *as;
- {
- register char *s;
-
- s = as;
- if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0)
- return(s[1]-'0');
- return(-1);
- }
-
- check()
- {
- register struct node *p, *lp;
-
- lp = &first;
- for (p=first.forw; p!=0; p = p->forw) {
- if (p->back != lp)
- abort();
- lp = p;
- }
- }
-
- source(ap)
- char *ap;
- {
- register char *p1, *p2;
-
- p1 = ap;
- p2 = p1;
- if (*p1==0)
- return(0);
- while (*p2++);
- if (*p1=='-' && *(p1+1)=='('
- || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='('
- || *(p2-2)=='+') {
- while (*p1 && *p1++!='r');
- if (*p1>='0' && *p1<='4')
- regs[*p1 - '0'][0] = 0;
- return(1);
- }
- return(0);
- }
-
- repladdr(p, f, flt)
- struct node *p;
- {
- register r;
- int r1;
- register char *p1, *p2;
- static char rt1[50], rt2[50];
-
- if (f)
- r1 = findrand(regs[RT2], flt);
- else
- r1 = -1;
- r = findrand(regs[RT1], flt);
- if (r1 >= NREG)
- r1 =- NREG;
- if (r >= NREG)
- r =- NREG;
- if (r>=0 || r1>=0) {
- p2 = regs[RT1];
- for (p1 = rt1; *p1++ = *p2++;);
- if (regs[RT2][0]) {
- p1 = rt2;
- *p1++ = ',';
- for (p2 = regs[RT2]; *p1++ = *p2++;);
- } else
- rt2[0] = 0;
- if (r>=0) {
- rt1[0] = 'r';
- rt1[1] = r + '0';
- rt1[2] = 0;
- nsaddr++;
- }
- if (r1>=0) {
- rt2[1] = 'r';
- rt2[2] = r1 + '0';
- rt2[3] = 0;
- nsaddr++;
- }
- p->code = copy(rt1, rt2);
- }
- }
-
- movedat()
- {
- register struct node *p1, *p2;
- struct node *p3;
- register seg;
- struct node data;
- struct node *datp;
-
- if (first.forw == 0)
- return;
- datp = &data;
- for (p1 = first.forw; p1!=0; p1 = p1->forw) {
- if (p1->op == DATA) {
- p2 = p1->forw;
- while (p2 && p2->op!=TEXT)
- p2 = p2->forw;
- if (p2==0)
- break;
- p3 = p1->back;
- p1->back->forw = p2->forw;
- p2->forw->back = p3;
- p2->forw = 0;
- datp->forw = p1;
- p1->back = datp;
- p1 = p3;
- datp = p2;
- }
- }
- if (data.forw) {
- datp->forw = first.forw;
- first.forw->back = datp;
- data.forw->back = &first;
- first.forw = data.forw;
- }
- seg = -1;
- for (p1 = first.forw; p1!=0; p1 = p1->forw) {
- if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) {
- if (p1->op == seg || p1->forw&&p1->forw->op==seg) {
- p1->back->forw = p1->forw;
- p1->forw->back = p1->back;
- p1 = p1->back;
- continue;
- }
- seg = p1->op;
- }
- }
- }
-
- redunbr(ap)
- struct node *ap;
- {
- register struct node *p, *p1;
- register char *ap1;
- char *ap2;
-
- if ((p1 = p->ref) == 0)
- return;
- p1 = nonlab(p1);
- if (p1->op==TST) {
- singop(p1);
- savereg(RT2, "$0");
- } else if (p1->op==CMP)
- dualop(p1);
- else
- return;
- if (p1->forw->op!=CBR)
- return;
- ap1 = findcon(RT1);
- ap2 = findcon(RT2);
- p1 = p1->forw;
- if (compare(p1->subop, ap1, ap2)) {
- nredunj++;
- nchange++;
- decref(p->ref);
- p->ref = p1->ref;
- p->labno = p1->labno;
- p->ref->refc++;
- }
- }
-
- findcon(i)
- {
- register char *p;
- register r;
-
- p = regs[i];
- if (*p=='$')
- return(p);
- if ((r = isreg(p)) >= 0)
- return(regs[r]);
- if (equstr(p, conloc))
- return(conval);
- return(p);
- }
-
- compare(op, acp1, acp2)
- char *acp1, *acp2;
- {
- register char *cp1, *cp2;
- register n1;
- int n2;
- struct { int i;};
-
- cp1 = acp1;
- cp2 = acp2;
- if (*cp1++ != '$' || *cp2++ != '$')
- return(0);
- n1 = 0;
- while (*cp2 >= '0' && *cp2 <= '7') {
- n1 =<< 3;
- n1 =+ *cp2++ - '0';
- }
- n2 = n1;
- n1 = 0;
- while (*cp1 >= '0' && *cp1 <= '7') {
- n1 =<< 3;
- n1 =+ *cp1++ - '0';
- }
- if (*cp1=='+')
- cp1++;
- if (*cp2=='+')
- cp2++;
- do {
- if (*cp1++ != *cp2)
- return(0);
- } while (*cp2++);
- cp1 = n1;
- cp2 = n2;
- switch(op) {
-
- case JEQ:
- return(cp1 == cp2);
- case JNE:
- return(cp1 != cp2);
- case JLE:
- return(cp1.i <= cp2.i);
- case JGE:
- return(cp1.i >= cp2.i);
- case JLT:
- return(cp1.i < cp2.i);
- case JGT:
- return(cp1.i > cp2.i);
- case JLO:
- return(cp1 < cp2);
- case JHI:
- return(cp1 > cp2);
- case JLOS:
- return(cp1 <= cp2);
- case JHIS:
- return(cp1 >= cp2);
- }
- return(0);
- }
-
- setcon(ar1, ar2)
- char *ar1, *ar2;
- {
- register char *cl, *cv, *p;
-
- cl = ar2;
- cv = ar1;
- if (*cv != '$')
- return;
- if (!natural(cl))
- return;
- p = conloc;
- while (*p++ = *cl++);
- p = conval;
- while (*p++ = *cv++);
- }
-
- equstr(ap1, ap2)
- char *ap1, *ap2;
- {
- char *p1, *p2;
-
- p1 = ap1;
- p2 = ap2;
- do {
- if (*p1++ != *p2)
- return(0);
- } while (*p2++);
- return(1);
- }
-
- setcc(ap)
- char *ap;
- {
- register char *p, *p1;
-
- p = ap;
- if (!natural(p)) {
- ccloc[0] = 0;
- return;
- }
- p1 = ccloc;
- while (*p1++ = *p++);
- }
-
- natural(ap)
- char *ap;
- {
- register char *p;
-
- p = ap;
- if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(')
- return(0);
- while (*p++);
- p--;
- if (*--p == '+' || *p ==')' && *--p != '5')
- return(0);
- return(1);
- }
-