📄 c20.c
字号:
} align->pop = 0; align->refc = 0; align->ref = NULL; align->labno = 0; prev = align; n_aligns++; } } prev = prev->forw; }}output(){ register struct node *t; int casebas; t = &first; while (t = t->forw) switch (t->op) { case END: fflush(stdout); return; case LABEL: printf("L%d:", t->labno); continue; case DLABEL: printf("%s:", t->code); continue; case CASE: casebas=0; default: std: if (t->pop==0) {/* must find it */ register struct optab *p; for (p=optab; p->opstring[0]; ++p) if (p->opcode==t->combop) {t->pop=p; break;} } printf("\t%s", t->pop->opstring); if (t->code) printf("\t%s", t->code); if (t->labno!=0) printf("%cL%d\n", (t->code ? ',' : '\t'), t->labno); else printf("\n"); continue; case MOVA: if (t->labno==0) goto std; printf("mova%c\tL%d,%s\n","bwlq"[t->subop-BYTE],t->labno,t->code); continue; case JSW: if (t->subop!=0) {/* F77JSW */ printf(".long\tL%d\n",t->labno); continue; } if (casebas==0) printf("L%d:\n",casebas=isn++); printf(".word L%d-L%d\n", t->labno, casebas); continue; case MOV: /* 005 */ if (t->forw) if(t->forw->op == CBR) goto std; if (*t->code == '$') goto std; if (t->subop == FFLOAT) { printf("movl\t%s\n", t->code); continue; } if (t->subop == DFLOAT || t->subop == GFLOAT) { printf("movq\t%s\n", t->code); continue; } if (t->subop == HFLOAT) { printf("movo\t%s\n", t->code); continue; } goto std; }}char *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);}#define OPHS 560struct optab *ophash[OPHS];opsetup(){ register struct optab *optp, **ophp; register int i,t; for(i=NREG+5;--i>=0;) regs[i]=alloc(C2_ASIZE); for (optp = optab; optp->opstring[0]; optp++) { t=7; i=0; while (--t>=0) i+= i+optp->opstring[t]; ophp = &ophash[i % OPHS]; while (*ophp++) {/* fprintf(stderr,"\ncollision: %d %s %s",/* ophp-1-ophash,optp->opstring,(*(ophp-1))->opstring);*/ if (ophp > &ophash[OPHS]) ophp = ophash; } *--ophp = optp; }}struct optab *oplook(){ register struct optab *optp,**ophp; register char *p,*p2; register int t; char tempop[20]; static struct optab OPNULL={"",0}; for (p=line, p2=tempop; *p && !isspace(*p); *p2++= *p++); *p2=0; p2=p; while (isspace(*p2)) ++p2; curlp=p2; t=0; while(--p>=line) t += t+*p; ophp = &ophash[t % OPHS]; while (optp = *ophp) { if (equstr(tempop,optp->opstring)) return(optp); if ((++ophp) >= &ophash[OPHS]) ophp = ophash; } curlp = line; return(&OPNULL);}refcount(){ register struct node *p, *lp; 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->combop==JBR || p->op==CBR || p->op==JSW || p->op==JMP || p->op==SOBGEQ || p->op==SOBGTR || p->op==AOBLEQ || p->op==AOBLSS || p->op==ACB || (p->op==MOVA && p->labno!=0)) { 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->labno!=rp->labno) { nbrbr++; p->labno = rp->labno; decref(p->ref); rp->ref->refc++; p->ref = rp->ref; nchange++; } } /* If a conditional branch is followed by an unconditional * branch to the same location, the conditional can be * eliminated. */ if (p->op==CBR) { p1 = nonlab(p->forw); if (p1->combop == JBR) { if (p->ref == p1->ref) { decref(p->ref); delnode(p); p = p1->back; nbrbr++; nchange++; continue; } } }#ifndef COPYCODE if (p->op==CBR && (p1 = p->forw)->combop==JBR) {/* combop: RET problems */#else if (p->op==CBR && (p1 = p->forw)->combop==JBR && p->ref) {/* combop: RET problems */#endif 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;#ifdef COPYCODE if (p->labno == 0) p->code = p1->code;#endif p1->forw->back = p; p->forw = p1->forw; p->subop = revbr[p->subop]; p->pop=0; nchange++; nskip++; } } if (p->op==JBR || p->op==JMP) { while (p->forw && p->forw->op!=LABEL && p->forw->op!=DLABEL && p->forw->op!=EROU && p->forw->op!=END && p->forw->op!=ALIGN && p->forw->op!=0 && p->forw->op!=DATA) { 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); } }}/* remove_branch_to_return * * Routine to remove uncontional branches which just branch to a * return. They are just replaced with a return. */static voidremove_branch_to_return(){ register struct node *ptr, /* Pointer to current instruction */ *dest, /* destination instruction for branch */ *nextdest; /* temporary for comparison */ int count; for ( ptr = first.forw; ptr != NULL; ptr = ptr->forw ) { if (ptr->combop == JBR || ptr->combop==JMP) { /* We have an unconditional jump/branch to a * label. Find the instruction after the * label(s), and if it is a return, convert * the jump/branch to the appropriate * return and decrease the reference to the * label. */ /* * Search through a list of unconditional * branches. These should have been * eliminated, but just in case. */ nextdest = ptr; dest = nonlab(ptr->ref); while ((dest != nextdest) /* L1: jmp L1 */ && (dest->combop == JBR || dest->combop == JMP)) { nextdest = dest; dest = nonlab(dest->ref); } if ((dest->combop == T(JBR,RET)) || (dest->combop == T(JBR,RSB)) ) { /* The unconditional branch/jump is to a * return, so just change it to a return. */ ptr->labno = 0; ptr->combop = dest->combop; ptr->pop = dest->pop; decref(ptr->ref); ptr->ref = NULL; nbrbr++; } } }}xjump(p1)register struct node *p1;{ register struct node *p2, *p3; int nxj; nxj = 0; 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->pop=0; p1->ref = p3; p1->labno = p3->labno; p1->code = 0; nxj++; nxjump++; nchange++; }}struct node *insertl(op)register struct node *op;{ register struct node *lp; 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);}struct node *codemove(ap)struct node *ap;{ register struct node *p1, *p2, *p3; struct node *t, *tl; int n; p1 = ap;/* last clause to avoid infinite loop on partial compiler droppings: L183: jbr L179 L191: jbr L179 casel r0,$0,$1 L193: .word L183-L193 .word L191-L193 L179: ret*/ if (p1->op!=JBR || (p2 = p1->ref)==0 || p2==p1->forw) 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]; p3->pop=0; 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;#ifdef COPYCODE if (p3->labno == 0) p3->code = p2->code;#endif 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 || p1->subop==RET || p1->subop==RSB)) 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->combop = JBR; /* to handle RET */ p2->pop=0; p2->labno = p3->labno;#ifdef COPYCODE p2->code = 0;#endif p2->ref = p3; nchange++; ncomj++; } else return; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -