⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c21.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	case INC:	case DEC:		splitrand(p);		dest(lastrand,p->subop);		if (p->op==CLR)			if ((r = isreg(regs[RT1])) >= 0)				savereg(r, "$0", p->subop);			else				setcon("$0", regs[RT1], p->subop);		break;/* .rx */	case TST:	case PUSH:		splitrand(p);		lastrand=regs[RT1+1]; /* fool repladdr into doing 1 operand */		repladdr(p);		if (p->op==TST && equstr(lastrand=regs[RT1], ccloc+1)		  && ((0xf&(ccloc[0]>>4))==p->subop || equtype(ccloc[0],p->subop))		  &&!source(lastrand)) {			delnode(p); p = p->back; nrtst++; nchange++;		}		setcc(lastrand,p->subop);		break;/* .rx,.rx,.rx */	case PROBER:	case PROBEW:	case CASE:	case MOVC3:/* .rx,.rx */	case MTPR:	case CALLS:	case CMP:	case BIT:		splitrand(p);		/* fool repladdr into doing right number of operands */		if (p->op==CASE || p->op==PROBER || p->op==PROBEW) lastrand=regs[RT4];/*		else if (p->op==CMPV || p->op==CMPZV) lastrand=regs[RT4+1]; */		else if (p->op==MOVC3) lastrand=regs[RT1];		else lastrand=regs[RT3];		repladdr(p);		if (p->op==CALLS || p->op==MOVC3) clearreg();		if (p->op==BIT) bitopt(p);		ccloc[0]=0; break;	case CBR:		if (p->subop>=JBC) {			splitrand(p);			if (p->subop<JBCC) lastrand=regs[RT3]; /* 2 operands can be optimized */			else lastrand=regs[RT2]; /* .mb destinations lose */			repladdr(p);		}		ccloc[0] = 0;		break;	case JBR:		redunbr(p);/* .wx,.bb */	case SOB:	default:		clearreg();	}	}}char *byondrd(p) register struct node *p; {/* return pointer to register which is "beyond last read/modify operand" */	if (OP2==(p->subop>>4)) return(regs[RT3]);	switch (p->op) {		case MFPR:		case JSB:		case PUSHA:		case TST: case INC: case DEC: case PUSH:	return(regs[RT2]);		case MTPR:		case BIT: case CMP: case CALLS:				return(regs[RT3]);		case PROBER: case PROBEW:		case CASE: case MOVC3:						return(regs[RT4]);	}	return(lastrand);}struct node *bflow(p)register struct node *p;{	register char *cp1,*cp2,**preg; register int r;	int flow= -1;	struct node *olduse=0;	splitrand(p);	if (p->op!=PUSH && p->subop && 0<=(r=isreg(lastrand)) && r<NUSE && uses[r]==p->forw) {	if (equtype(p->subop,regs[r][0])	|| ((p->op==CVT || p->op==MOVZ)			 && 0xf&regs[r][0] && compat(0xf&(p->subop>>4),regs[r][0]))) {		register int r2;		if (regs[r][1]!=0) {/* send directly to destination */			if (p->op==INC || p->op==DEC) {				if (p->op==DEC) p->op=SUB; else p->op=ADD;				p->subop=(OP2<<4)+(p->subop&0xF); /* use 2 now, convert to 3 later */				p->pop=0;				cp1=lastrand; cp2=regs[RT2]; while (*cp2++= *cp1++); /* copy reg */				cp1=lastrand; *cp1++='$'; *cp1++='1'; *cp1=0;			}			cp1=regs[r]+1; cp2=lastrand;			if (OP2==(p->subop>>4)) {/* use 3 operand form of instruction */				p->pop=0;				p->subop += (OP3-OP2)<<4; lastrand=cp2=regs[RT3];			}			while (*cp2++= *cp1++);			if (p->op==MOVA && p->forw->op==PUSH) {				p->op=PUSHA; *regs[RT2]=0; p->pop=0;			} else if (p->op==MOV && p->forw->op==PUSH) {				p->op=PUSH ; *regs[RT2]=0; p->pop=0;			}			delnode(p->forw);			if (0<=(r2=isreg(lastrand)) && r2<NUSE) {				uses[r2]=uses[r]; uses[r]=0;			}			redun3(p,0);			newcode(p); redunm++; flow=r;		} else if (p->op==MOV && p->forw->op!=EXTV && p->forw->op!=EXTZV) {			/* superfluous fetch */			int nmatch;			char src[C2_ASIZE];	movit:			cp2=src; cp1=regs[RT1]; while (*cp2++= *cp1++);			splitrand(p->forw);			if (p->forw->op != INC && p->forw->op != DEC)				lastrand=byondrd(p->forw);			nmatch=0;			for (preg=regs+RT1;*preg!=lastrand;preg++)				if (r==isreg(*preg)) {				cp2= *preg; cp1=src; while (*cp2++= *cp1++); ++nmatch;			}			if (nmatch==1) {				if (OP2==(p->forw->subop>>4) && equstr(src,regs[RT2])) {					p->forw->pop=0;					p->forw->subop += (OP3-OP2)<<4; cp1=regs[RT3];					*cp1++='r'; *cp1++=r+'0'; *cp1=0;				}				delnode(p); p=p->forw;				if (0<=(r2=isreg(src)) && r2<NUSE) {					uses[r2]=uses[r]; uses[r]=0;				}				redun3(p,0);				newcode(p); redunm++; flow=r;			} else splitrand(p);		}	} else if (p->op==MOV && (p->forw->op==CVT || p->forw->op==MOVZ)		&& p->forw->subop&0xf 	/* if base or index, then forget it */		&& compat(p->subop,p->forw->subop) && !source(cp1=regs[RT1])		&& !indexa(cp1)) goto movit;	}	/* adjust 'lastrand' past any 'read' or 'modify' operands. */	lastrand=byondrd(p);	/* a 'write' clobbers the register. */	if (0<=(r=isreg(lastrand)) && r<NUSE	|| OP2==(p->subop>>4) && 0<=(r=isreg(regs[RT2])) && r<NUSE && uses[r]==0) {		/* writing a dead register is useless, but watch side effects */		switch (p->op) {		case ACB:		case AOBLEQ: case AOBLSS: case SOBGTR: case SOBGEQ: break;		default:			if (uses[r]==0) {/* no direct uses, check for use of condition codes */				register struct node *q=p;				while ((q=nonlab(q->forw))->combop==JBR) q=q->ref;	/* cc unused, unchanged */				if (q->op!=CBR) {/* ... and destroyed */					preg=regs+RT1;					while (cp1= *preg++) {						if (cp1==lastrand) {redunm++; delnode(p); return(p->forw);}						if (source(cp1) || equstr(cp1,lastrand)) break;					}				}			}			flow=r;		}	}	if (0<=(r=flow)) {olduse=uses[r]; uses[r]=0; *(short *)(regs[r])=0;}		/* these two are here, rather than in bmove(),		/* because I decided that it was better to go for 3-address code		/* (save time) rather than fancy jbxx (save 1 byte)		/* on sequences like  bisl2 $64,r0; movl r0,foo		*/	if (p->op==BIC) {p=bicopt(p); splitrand(p); lastrand=byondrd(p);}	if (p->op==BIS) {bixprep(p,JBSS);           lastrand=byondrd(p);}	/* now look for 'read' or 'modify' (read & write) uses */	preg=regs+RT1; 	while (*(cp1= *preg++)) {		/* check for  r  */		if (lastrand!=cp1 && 0<=(r=isreg(cp1)) && r<NUSE && uses[r]==0) {			uses[r]=p; cp2=regs[r]; *cp2++=p->subop;			if (p->op==ASH && preg==(regs+RT1+1)) cp2[-1]=BYTE; /* stupid DEC */			if (p->op==MOV || p->op==PUSH || p->op==CVT || p->op==MOVZ || p->op==COM || p->op==NEG) {				if (p->op==PUSH) cp1="-(sp)";				else {					cp1=regs[RT2];					if (0<=(r=isreg(cp1)) && r<NUSE && uses[r]==0)						uses[r]=olduse; /* reincarnation!! */					/* as in  addl2 r0,r1;  movl r1,r0;  ret  */					if (p->op!=MOV) cp1=0;				}				if (cp1) while (*cp2++= *cp1++);				else *cp2=0;			} else *cp2=0;			continue;		}		/* check for (r),(r)+,-(r),[r] */		do if (*cp1=='(' || *cp1=='[') {/* get register number */			char t;			cp2= ++cp1; while (*++cp1!=')' && *cp1!=']'); t= *cp1; *cp1=0;			if (0<=(r=isreg(cp2)) && r<NUSE && (uses[r]==0 || uses[r]==p)) {				uses[r]=p; regs[r][0]=(*--cp2=='[' ? OPX<<4 : OPB<<4);			}			*cp1=t;		} while (*++cp1);	}	/* pushax or movax possibility? */	cp1=regs[RT1];	if (*cp1++=='$' && isstatic(cp1) && natural(regs[RT1])) {		if (p->combop==T(MOV,LONG)) {			if (regs[RT1][1]=='L' && 0!=(p->labno=getnum(regs[RT1]+2))) {				cp1=p->code; while (*cp1++!=','); p->code= --cp1;			}			p->combop=T(MOVA,LONG); ++p->code; p->pop=0;		} else if (p->combop==T(PUSH,LONG)) {			p->combop=T(PUSHA,LONG); ++p->code; p->pop=0;		} else if ((p->combop&0xFFFF)==T(ADD,U(LONG,OP3))				 && 0<=(r=isreg(regs[RT2]))) {			cp1=cp2=p->code; ++cp1;			do *cp2++= *cp1; while (*cp1++!=','); cp2[-1]='[';			do *cp2++= *cp1; while (*cp1++!=','); cp2[-1]=']';			if (!equstr(regs[RT3],"-(sp)")) p->combop=T(MOVA,BYTE);			else {p->combop=T(PUSHA,BYTE); *cp2=0;}			if (uses[r]==0) {uses[r]=p; regs[r][0]=OPX<<4;}			p->pop=0;		}	}	return(p);}ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */	register int log;	if (n==0 || n&(n-1)) return(-1); log=0;	for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}}bitopt(p) register struct node *p; {	/* change "bitx $<power_of_2>,a" followed by JEQ or JNE	/* into JBC or JBS.  watch out for I/O registers. (?)	/* assumes that 'splitrand' has already been called.	*/	register char *cp1,*cp2; int b;	cp1=regs[RT1]; cp2=regs[RT2];	if (*cp1++!='$' || !okio(cp2) || p->forw->op!=CBR || p->forw->subop&-2 ||		0>(b=ispow2(getnum(cp1))) ||		p->subop!=BYTE && (source(cp2) || indexa(cp2))) return;	if (b>=bitsize[p->subop]) {/* you dummy! */		if (source(cp2)) {/* side effect: auto increment or decrement */			p->pop=0;			p->op=TST; --cp1; while (*cp1++= *cp2++);			regs[RT2][0]=0; newcode(p);		} else delnode(p);		p = p->forw;		if (p->subop==JEQ) {p->combop=JBR; p->pop=0;}		else delnode(p);		nchange++; nbj++; return;	}	if (cp1=p->forw->code) {/* destination is not an internal label */		cp2=regs[RT3]; while (*cp2++= *cp1++);	}	if (b==0 && (p->subop==LONG || !indexa(regs[RT2]))) {/* JLB optimization, ala BLISS */		cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++);		cp2=regs[RT2]; cp1=regs[RT3]; while (*cp2++= *cp1++);		*(regs[RT3])=0; p->forw->subop += JLBC-JBC;		p->forw->pop=0;	} else {		cp1=regs[RT1]+1;		if (b>9) *cp1++= b/10 +'0'; *cp1++= b%10 +'0'; *cp1=0; /* $<bit_number> */	}	nbj++; newcode(p); p->combop = p->forw->combop+((JBC-JEQ)<<8);	p->labno = p->forw->labno; delnode(p->forw);	p->pop=0;}isfield(n) register long n; {/* -1 -> no; else -> position of low bit */	register int pos; register long t;	t= ((n-1)|n) +1;	if (n!=0 && (0==t || 0==n || 0<=ispow2(t))) {		pos=0; while(!(n&1)) {n >>= 1; ++pos;} return(pos);	} else return(-1);}bixprep(p,bix) register struct node *p; {/* initial setup, single-bit checking for bisopt, bicopt./* return: 0->don't bother any more; 1->worthwhile trying*/	register char *cp1,*cp2;	splitrand(p); cp1=regs[RT1]; cp2=regs[RT2];	if (*cp1++!='$' || 0>(pos=isfield(f=getnum(cp1)))	  || !okio(cp2) || indexa(cp2) || source(cp2) || !okio(lastrand)) return(0);	f |= f-1; if (++f==0) siz=32-pos; else siz=ispow2(f)-pos;	if (siz==1 && pos>5 && (p->subop>>4)==OP2 && (p->subop&0xF)!=BYTE	  && pos<bitsize[p->subop&0xF]) {		p->ref = insertl(p->forw); p->combop = CBR | (bix<<8);		p->pop=0;		p->labno = p->ref->labno;		if (pos>9) {*cp1++= pos/10 +'0'; pos %= 10;}		*cp1++=pos+'0'; *cp1=0; newcode(p); nbj++; return(0);	}	return(1);}struct node *bicopt(p) register struct node *p; {/* use field operations or MOVZ if possible.  done as part of 'bflow'.*/	register char *cp1,*cp2; int r;	char src[C2_ASIZE];	if (!bixprep(p,JBCC)) return(p);	if (f==0) {/* the BIC isolates low order bits */		siz=pos; pos=0;		if ((p->subop&0xF)==LONG && *(regs[RT2])!='$') {/* result of EXTZV is long */			/* save source of BICL in 'src' */			cp1=regs[RT2]; cp2=src; while (*cp2++= *cp1++);			if (p->back->op==ASH) {/* try for more */				splitrand(p->back); cp1=regs[RT1]; cp2=regs[RT3];				if (*cp1++=='$' && *(regs[RT2])!='$' && !indexa(regs[RT2])				  && 0>(f=getnum(cp1)) && equstr(src,cp2)				  && 0<=(r=isreg(cp2)) && r<NUSE) {/* a good ASH */					pos -= f; cp1=regs[RT2]; cp2=src; while (*cp2++= *cp1++);					delnode(p->back);				}			}			if (p->back->op==CVT || p->back->op==MOVZ) {/* greedy, aren't we? */				splitrand(p->back); cp1=regs[RT1]; cp2=regs[RT2];				if (equstr(src,cp2) && okio(cp1) && !indexa(cp1)				  && 0<=(r=isreg(cp2)) && r<NUSE				  && bitsize[p->back->subop&0xF]>=(pos+siz)				  && bitsize[p->back->subop>>4]>=(pos+siz)) {/* good CVT */					cp1=regs[RT1]; cp2=src; while (*cp2++= *cp1++);					delnode(p->back);				}			}			/* 'pos', 'siz' known; source of field is in 'src' */			splitrand(p); /* retrieve destination of BICL */			if (siz==8 && pos==0) {				p->combop = T(MOVZ,U(BYTE,LONG));				sprintf(line,"%s,%s",src,lastrand);			} else {				p->combop = T(EXTZV,LONG);				sprintf(line,"$%d,$%d,%s,%s",pos,siz,src,lastrand);			}			p->pop=0;			p->code = copy(line); nfield++; return(p);		}/* end EXTZV possibility */	}/* end low order bits *//* unfortunately, INSV clears the condition codes, thus cannot be used *//*	else {/* see if BICL2 of positive field should be INSV $0 *//*		if (p->subop==(LONG | (OP2<<4)) && 6<=(pos+siz)) {/*			p->combop = INSV;/*			sprintf(line,"$0,$%d,$%d,%s",pos,siz,lastrand);/*			p->code = copy(line); nfield++; return(p);/*		}/*	}*/	return(p);}jumpsw(){	register struct node *p, *p1;	register t;	int nj;	t = 0;	nj = 0;	for (p=first.forw; p!=0; p = p->forw)		p->seq = ++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->seq - p->ref->seq) > abs(p1->seq - p1->ref->seq)) {			if (p->ref==p1->ref)				continue;			p->subop = revbr[p->subop];			p->pop=0;			t = p1->ref;			p1->ref = p->ref;			p->ref = t;			t = p1->labno;			p1->labno = p->labno;			p->labno = t;#ifdef COPYCODE			if (p->labno == 0) {				t = p1->code; p1->code = p->code; p->code = t;			}#endif			nrevbr++;			nj++;		}	}	return(nj);}addsob(){	register struct node *p, *p1, *p2, *p3;	for (p = &first; (p1 = p->forw)!=0; p = p1) {	if (p->combop==T(DEC,LONG) && p1->op==CBR) {		if (abs(p->seq - p1->ref->seq) > 8) continue;		if (p1->subop==JGE || p1->subop==JGT) {			if (p1->subop==JGE) p->combop=SOBGEQ; else p->combop=SOBGTR;			p->pop=0;			p->labno = p1->labno; delnode(p1); nsob++;		}	} else if (p->combop==T(INC,LONG)) {		if (p1->op==LABEL && p1->refc==1 && p1->forw->combop==T(CMP,LONG)		  && (p2=p1->forw->forw)->combop==T(CBR,JLE)		  && (p3=p2->ref->back)->combop==JBR && p3->ref==p1		  && p3->forw->op==LABEL && p3->forw==p2->ref) {			/* change	INC LAB: CMP	to	LAB: INC CMP */			p->back->forw=p1; p1->back=p->back;			p->forw=p1->forw; p1->forw->back=p;			p->back=p1; p1->forw=p;			p1=p->forw;			/* adjust beginning value by 1 */				p2=alloc(sizeof first); p2->combop=T(DEC,LONG);				p2->pop=0;				p2->forw=p3; p2->back=p3->back; p3->back->forw=p2;				p3->back=p2; p2->code=p->code; p2->labno=0;		}		if (p1->combop==T(CMP,LONG) && (p2=p1->forw)->op==CBR) {			register char *cp1,*cp2;			splitrand(p1); if (!equstr(p->code,regs[RT1])) continue;			if (abs(p->seq - p2->ref->seq)<8) {/* inside byte displ range */				if (p2->subop!=JLE) continue;				/*				 * acbl take twice as long as aobleq				 * so changed to aobleq - dm 1/19/82				 */				p->combop=AOBLEQ;				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++;			} else			if (abs(p->seq - p2->ref->seq)>8) {/* outside byte displ range */				if (p2->subop!=JLE) continue;				p->combop=T(ACB,LONG);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -