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

📄 c21.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
register char *s;{	register int i;	(void) source(s); /* handle addressing side effects */	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;		return;	}	if ((i = isreg(s)) >= 0) {		/* if register destination, that reg is a goner */		*(short *)(regs[i]) = 0;		switch(type & 0xF){		case DFLOAT:	/* clobber two at once */			/*FALLTHROUGH*/		case GFLOAT:			*(short *)(regs[i+1]) = 0;			break;		case HFLOAT:	/* clobber four at once */			*(short *)(regs[i+1]) = 0;			*(short *)(regs[i+2]) = 0;			*(short *)(regs[i+3]) = 0;			break;		}		switch((type>>4)&0xF){		case DFLOAT:	/* clobber two at once */			/*FALLTHROUGH*/		case GFLOAT:			*(short *)(regs[i+1]) = 0;			break;		case HFLOAT:	/* clobber four at once */			*(short *)(regs[i+1]) = 0;			*(short *)(regs[i+2]) = 0;			*(short *)(regs[i+3]) = 0;			break;		}	}	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 (*conloc && equstr(conloc, s))		conloc[0] = 0;	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)/* See if the the operand types are compatible. "have" contains the source * and destination types for an instruction (which we may be trying to * replace).  "want" contains the operand type we want as a result.  DLB003 */{	register int	wanted_type,	/* Type we want to end with	*/			src_type,	/* Source type of instruction	*/			dst_type;	/* Destination type of "	*/	/* Get "wanted_type" from "want" and if it is 0 then we have	 * wildcard request so anything matches.	 */	if ( (wanted_type = (want & 0xF)) == 0)		return(1);	/* Extract the source and destination tyes from "have".  If the	 * destination type is wildcard or one of the OPx types then make	 * it the same as the source.				DLB003	 */	src_type=have&0xF;	dst_type=((have>>4)&0xF);	if (dst_type==0 || (dst_type>=OP2 && dst_type<=OPX))		dst_type=src_type;	/* If the wanted_type is not BYTE, WORD, or LONG, then the	 * types are compatible only if all three are the same.	DLB003	 */	if (wanted_type>=FFLOAT)		return(dst_type==wanted_type && 		       src_type==wanted_type);	/* Otherwise, the types are compatible only if the the destination	 * type is a BYTE, WORD, or LONG and both the destination and	 * sources types are larger than the wanted type.	DLB003	 */	return(dst_type<FFLOAT &&	       dst_type>=wanted_type &&	       src_type>=wanted_type );}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)		  ) {		/* The results of the TST aren't used, so we can just		 * branch past it.  Insert a new label in front of the		 * TST, dereference the old label, and set up the branch		 * to go to the new label.		 */		p1=insertl(p1->forw);		decref(p->ref);		p->ref = p1;		p->labno = p1->labno;		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);}autoid(p)	register char *p ;	/* operand address string *//* See if operand addressing mode uses auto(in|de)crement. * Return 1 for yes, 0 for no. */{	if (*p == '-' && *(p+1) == '(') return(1) ; /* autodecrement	  */	while (*p) p++;				    /* find end of string */	if (*--p == '+' && *--p == ')') return(1) ; /* autoincrement	  */	return(0) ;				    /* neither		  */}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 + -