📄 c21.c
字号:
cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */ cp2=regs[RT2]; cp1="$1"; while (*cp2++= *cp1++); cp2=regs[RT3]; cp1=p->code; while (*cp2++= *cp1++); p->pop=0; newcode(p); p->labno = p2->labno; delnode(p2); delnode(p1); nsob++; } else if (p2->subop==JLE || p2->subop==JLT) { if (p2->subop==JLE) p->combop=AOBLEQ; else p->combop=AOBLSS; cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */ cp2=regs[RT2]; cp1=p->code; while (*cp2++= *cp1++); /* index */ p->pop=0; newcode(p); p->labno = p2->labno; delnode(p2); delnode(p1); nsob++; } } } }}abs(x){ return(x<0? -x: x);}equop(p1, p2)register struct node *p1;struct node *p2;{ register char *cp1, *cp2; if (p1->combop != p2->combop) return(0); if (p1->op>0 && p1->op<MOV) return(0); if (p1->op==MOVA && p1->labno!=p2->labno) 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);}delnode(p) register struct node *p; { p->back->forw = p->forw; p->forw->back = p->back;}decref(p)register struct node *p;{ if (p && --p->refc <= 0) { nrlab++; delnode(p); }}struct node *nonlab(ap)struct node *ap;{ register struct node *p; p = ap; while (p && p->op==LABEL) p = p->forw; return(p);}clearuse() { register struct node **i; for (i=uses+NUSE; i>uses;) *--i=0;}clearreg() { register short **i; for (i=regs+NREG; i>regs;) **--i=0; conloc[0] = 0; ccloc[0] = 0;}savereg(ai, s, type)register char *s;{ register char *p, *sp; sp = p = regs[ai]; if (source(s)) /* side effects in addressing */ return; /* if any indexing, must be parameter or local */ /* indirection (as in "*-4(fp)") is ok, however */ *p++ = type; while (*p++ = *s) if (*s=='[' || *s++=='(' && *s!='a' && *s!='f') {*sp = 0; return;}}dest(s,type)register char *s;{ register int i; source(s); /* handle addressing side effects */ if ((i = isreg(s)) >= 0) { *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */ if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF)) *(short *)(regs[i+1]) = 0; /* clobber two at once */ } for (i=NREG; --i>=0;) if (regs[i][1]=='*' && equstr(s, regs[i]+2)) *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */ while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */ *(short *)(regs[i]) = 0; if (!natural(s)) {/* wild store, everything except constants vanishes */ for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0; conloc[0] = 0; ccloc[0] = 0; } else setcc(s,type); /* natural destinations set condition codes */}splitrand(p) struct node *p; {/* separate operands at commas, set up 'regs' and 'lastrand' */register char *p1, *p2; register char **preg;preg=regs+RT1;if (p1=p->code) while (*p1) { lastrand=p2= *preg++; while (*p1) if (','==(*p2++= *p1++)) {--p2; break;} *p2=0;}while (preg<(regs+RT1+5)) *(*preg++)=0;}compat(have, want) {register int hsrc, hdst;if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;if (want>=FLOAT) return(hdst==want && hsrc==want); /* FLOAT, DOUBLE not compat: rounding */return(hsrc>=want && hdst>=want && hdst<FLOAT);}equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}findrand(as, type)char *as;{ register char **i; for (i = regs+NREG; --i>=regs;) { if (**i && equstr(*i+1, as) && compat(**i,type)) return(i-regs); } return(-1);}isreg(s)register char *s;{ if (*s++!='r' || !isdigit(*s++)) return(-1); if (*s==0) return(*--s-'0'); if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'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(-1); lp = p; }}source(ap)char *ap;{ register char *p1, *p2; p1 = ap; p2 = p1; if (*p1==0) return(0); while (*p2++ && *(p2-1)!='['); if (*p1=='-' && *(p1+1)=='(' || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='(' || *(p2-2)=='+') { while (*p1 && *p1++!='r'); if (isdigit(*p1++)) if (isdigit(*p1)) *(short *)(regs[10+*p1-'0'])=0; else *(short *)(regs[*--p1-'0'])=0; return(1); } return(0);}newcode(p) struct node *p; { register char *p1,*p2,**preg; preg=regs+RT1; p2=line; while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';} *--p2=0; p->code=copy(line);}repladdr(p)struct node *p;{ register r; register char *p1, *p2; char **preg; int nrepl; preg=regs+RT1; nrepl=0; while (lastrand!=(p1= *preg++)) if (!source(p1) && 0<=(r=findrand(p1,p->subop))) { *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0; nrepl++; nsaddr++; } if (nrepl) newcode(p);}/* 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(p)register struct node *p;{ register struct node *p1; register char *ap1; char *ap2; if ((p1 = p->ref) == 0) return; p1 = nonlab(p1); if (p1->op==TST) { splitrand(p1); savereg(RT2, "$0", p1->subop); } else if (p1->op==CMP) splitrand(p1); else return; if (p1->forw->op==CBR) { ap1 = findcon(RT1, p1->subop); ap2 = findcon(RT2, p1->subop); p1 = p1->forw; if (compare(p1->subop, ap1, ap2)) { nredunj++; nchange++; decref(p->ref); p->ref = p1->ref; p->labno = p1->labno;#ifdef COPYCODE if (p->labno == 0) p->code = p1->code; if (p->ref)#endif p->ref->refc++; } } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) && equtype(ccloc[0],p1->subop)) { p1=insertl(p1->forw); decref(p->ref); p->ref=p1; nrtst++; nchange++; }}char *findcon(i, type){ register char *p; register r; p = regs[i]; if (*p=='$') return(p); if ((r = isreg(p)) >= 0 && compat(regs[r][0],type)) return(regs[r]+1); if (equstr(p, conloc)) return(conval+1); return(p);}compare(op, acp1, acp2)char *acp1, *acp2;{ register char *cp1, *cp2; register n1; int n2; int sign; cp1 = acp1; cp2 = acp2; if (*cp1++ != '$' || *cp2++ != '$') return(0); n1 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;} while (isdigit(*cp2)) {n1 *= 10; n1 += (*cp2++ - '0')*sign;} n2 = n1; n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;} while (isdigit(*cp1)) {n1 *= 10; n1 += (*cp1++ - '0')*sign;} 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(((int)cp1) <= ((int)cp2)); case JGE: return(((int)cp1) >= ((int)cp2)); case JLT: return(((int)cp1) < ((int)cp2)); case JGT: return(((int)cp1) > ((int)cp2)); case JLO: return(cp1 < cp2); case JHI: return(cp1 > cp2); case JLOS: return(cp1 <= cp2); case JHIS: return(cp1 >= cp2); } return(0);}setcon(cv, cl, type)register char *cv, *cl;{ register char *p; if (*cv != '$') return; if (!natural(cl)) return; p = conloc; while (*p++ = *cl++); p = conval; *p++ = type; while (*p++ = *cv++);}equstr(p1, p2)register char *p1, *p2;{ do { if (*p1++ != *p2) return(0); } while (*p2++); return(1);}setcc(ap,type)char *ap;{ register char *p, *p1; p = ap; if (!natural(p)) { ccloc[0] = 0; return; } p1 = ccloc; *p1++ = type; while (*p1++ = *p++);}okio(p) register char *p; {/* 0->probable I/O space address; 1->not */ if (ioflag && (!natural(p) || 0>getnum(p))) return(0); return(1);}indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */ while (*p) if (*p++=='[') return(1); return(0);}natural(p)register char *p;{/* 1->simple local, parameter, global, or register; 0->otherwise */ if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(' || *p=='$'&&getnum(p+1)) return(0); while (*p++); p--; if (*--p=='+' || *p==']' || *p==')' && *(p-2)!='a' && *(p-2)!='f') return(0); return(1);}/*** Tell if an argument is most likely static.*/isstatic(cp)register char *cp;{ if (*cp == '_' || *cp == 'L' || (*cp++ == 'v' && *cp == '.')) return (1); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -