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

📄 c21.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
static	char sccsid[] = "@(#)c21.c 4.7 7/8/81";/* char C21[] = {"@(#)c21.c 1.83 80/10/16 21:18:22 JFR"}; /* sccs ident *//* * C object code improver-- second part */#include "c2.h"#include <stdio.h>#include <ctype.h>#define NUSE 6int ioflag;int biti[NUSE] = {1,2,4,8,16,32};int bitsize[4] = {0,8,16,32}; /* index by type codes */int pos,siz; long f; /* for bit field communication */struct node *uses[NUSE]; /* for backwards flow analysis */char *lastrand; /* last operand of instruction */struct node *bflow();struct node *bicopt();char *findcon();redun3(p,split) register struct node *p; int split; {/* check for 3 addr instr which should be 2 addr */	if (OP3==((p->subop>>4)&0xF)) {		if (split) splitrand(p);		if (equstr(regs[RT1],regs[RT3])		  && (p->op==ADD || p->op==MUL || p->op==BIS || p->op==XOR)) {			register char *t=regs[RT1]; regs[RT1]=regs[RT2]; regs[RT2]=t;		}		if (equstr(regs[RT2],regs[RT3])) {			p->subop=(p->subop&0xF)|(OP2<<4); p->pop=0;			lastrand=regs[RT2]; *regs[RT3]=0; return(1);		}	} return(0);}bmove() {	register struct node *p, *lastp; register char *cp1,*cp2; register int r;	refcount();	for (p=lastp= &first; 0!=(p=p->forw); lastp=p);	clearreg(); clearuse();	for (p=lastp; p!= &first; p=p->back) {	if (debug) {		printf("Uses:\n");		for (r=NUSE;--r>=0;) if (uses[r])			printf("%d: %s\n",r,uses[r]->code? uses[r]->code:"");		printf("-\n");	}	r=(p->subop>>4)&0xF;	if (OP2==r && (cp1=p->code, *cp1++)=='$' && *cp1++=='0' && *cp1++==',' &&			!source(cp1)) {/* a no-op unless MUL or DIV */		if (p->op==MUL) {p->op=MOV; p->subop&=0xF; p->pop=0;}		else if (p->op==DIV) fprintf(stderr,"c2: zero divide\n");		else {delnode(p); redunm++; continue;}	}	if (OP3==r && 0!=redun3(p,1)) {newcode(p); redunm++;}	switch (p->op) {	case LABEL: case DLABEL:		for (r=NUSE; --r>=0;)			if (uses[r]) p->ref=(struct node *) (((int)p->ref)|biti[r]);		break;	case CALLS:		clearuse(); goto std;	case 0:		clearuse(); break;	case SUB:		if ((p->subop&0xF)!=LONG) goto std; cp1=p->code;		if (*cp1++!='$') goto std; splitrand(p);		if (equstr(regs[RT2],"fp") && !indexa(regs[RT1])) {/* address comp. */			char buf[C2_ASIZE]; cp2=buf; *cp2++='-'; 			cp1=regs[RT1]+1; while (*cp2++= *cp1++); --cp2;			cp1="(fp),"; while (*cp2++= *cp1++); --cp2;			cp1=regs[RT3]; while (*cp2++= *cp1++);			p->code=copy(buf); p->combop=T(MOVA,LONG); p->pop=0;		} else if (*cp1++=='-' && 0<=(r=getnum(cp1))) {			p->op=ADD; p->pop=0; *--cp1='$'; p->code=cp1;		} goto std;	case ADD:		if ((p->subop&0xF)!=LONG) goto std; cp1=p->code;		if (*cp1++!='$') goto std; splitrand(p);		if (isstatic(cp1) && (r=isreg(regs[RT2]))>=0 && r<NUSE && uses[r]==p->forw)		{			/* address comp:			**	addl2	$_foo,r0  \	movab	_foo[r0],bar			**	movl	r0,bar	  /			*/			register struct	node	*pnext = p->forw;			char	buf[C2_ASIZE];			if (pnext->op == MOV && pnext->subop == LONG)			{				cp1 = &regs[RT1][1]; cp2 = &buf[0];				while (*cp2++ = *cp1++) ; cp2--;				splitrand(pnext);				if (r == isreg(regs[RT1]))				{					delnode(p); p = pnext;					p->op = MOVA; p->subop = BYTE;					p->pop = 0;					cp1 = regs[RT1]; *cp2++ = '[';					while (*cp2++ = *cp1++) ; cp2--;					*cp2++ = ']'; *cp2++ = ',';					cp1 = regs[RT2];					while (*cp2++ = *cp1++) ;					p->code = copy(buf);				}			}		}		else		if (equstr(regs[RT2],"fp") && !indexa(regs[RT1])) {/* address comp. */			cp2=cp1-1; cp1=regs[RT1]+1; while (*cp2++= *cp1++); --cp2;			cp1="(fp)"; while (*cp2++= *cp1++); *--cp2=',';			p->combop=T(MOVA,LONG); p->pop=0;		} else if (*cp1++=='-' && 0<=(r=getnum(cp1))) {			p->op=SUB; p->pop=0; *--cp1='$'; p->code=cp1;		}		/* fall thru ... */	case CASE:	default: std:		p=bflow(p); break;	case MUL:	{		/*		** Change multiplication by constant powers of 2 to		**	shifts.		*/		splitrand(p);		if (regs[RT1][0] != '$' || regs[RT1][1] == '-') goto std;		if ((r = ispow2(getnum(&regs[RT1][1]))) < 0) goto std;		switch (r)		{		case 0:		/* mull3 $1,x,y */			if (p->subop == U(LONG,OP3))			{				if (equstr(regs[RT2], regs[RT3]))				{					delnode(p); p = p->forw;				}				else				{					p->op = MOV; p->subop = LONG;					p->pop = 0; newcode(p); nchange++;				}			}			else			if (p->subop == U(LONG,OP2))			{				delnode(p); p = p->forw;			}			goto std;		case 1:		/* mull2 $2,x */			if (p->subop == U(LONG, OP2) && !source(regs[RT2]))			{				strcpy(regs[RT1], regs[RT2]);				p->op = ADD; p->pop = 0; newcode(p); nchange++;			}			goto std;		}		if(p->subop==U(LONG,OP3)||(p->subop==U(LONG,OP2)&&!source(regs[RT2])))		{			if (p->subop == U(LONG,OP2))				strcpy(regs[RT3], regs[RT2]);			sprintf(regs[RT1], "$%d", r);			p->op = ASH; p->subop = LONG;			p->pop = 0; newcode(p); nchange++;		}		goto std;	}	case ASH:	{		/* address comp:		**	ashl	$1,bar,r0  \	movl	bar,r0		**	movab	_foo[r0]   /	movaw	_foo[r0]		**		**	ashl	$2,r0,r0   \	moval	_foo[r0]		**	movab	_foo[r0]   /		*/		register struct	node	*pf;		register int	shfrom, shto;		long	shcnt;		char	*regfrom;		splitrand(p);		if (regs[RT1][0] != '$') goto std;		if ((shcnt = getnum(&regs[RT1][1])) < 1 || shcnt > 3) goto std;		if ((shfrom = isreg(regs[RT2])) >= 0)			regfrom = copy(regs[RT2],"]");		if ((shto = isreg(regs[RT3])) >= 0 && shto<NUSE)		{			int	regnum;			if (uses[shto] != (pf = p->forw)) goto ashadd;			if (pf->op != MOVA && pf->op != PUSHA) goto ashadd;			if (pf->subop != BYTE) goto ashadd;			splitrand(pf);			if (!indexa(regs[RT1])) goto std;			cp2 = regs[RT1];			if(!isstatic(cp2)) goto std;			while (*cp2++ != '[') ;			if (*cp2++ != 'r' || !isdigit(*cp2)) goto std;			regnum = *cp2++ - '0';			if (isdigit(*cp2))			{				if (cp2[1] != ']') goto std;				regnum *= 10; regnum += *cp2 - '0';			}			if (regnum != shto) goto std;			if (shfrom >= 0)	/* ashl $N,r*,r0 */			{				delnode(p);				if (shfrom != shto)				{					uses[shto] = NULL; splitrand(pf);					cp2=regs[RT1]; while (*cp2++!='[');					cp1=regfrom; while (*cp2++= *cp1++);					newcode(pf);				}			}			else			{				p->op = MOV; splitrand(p);				strcpy(regs[RT1], regs[RT2]);				strcpy(regs[RT2], regs[RT3]);				regs[RT3][0] = '\0';				p->pop = 0; newcode(p);			}			switch (shcnt)			{			case 1:	pf->subop = WORD; break;			case 2:	pf->subop = LONG; break;			case 3:	pf->subop = QUAD; break;			}			redunm++; nsaddr++; nchange++;		}		goto std;ashadd:		/* at this point, RT2 and RT3 are guaranteed to be simple regs*/		if (shcnt == 1 && equstr(regs[RT2], regs[RT3]))		{			/*			** quickie:			**	ashl	$1,A,A	>	addl2	A,A			*/			p->op = ADD; p->subop = U(LONG,OP2); p->pop = 0;			strcpy(regs[RT1], regs[RT2]); regs[RT3][0] = '\0';			newcode(p); nchange++;		}		goto std;	}	case EXTV:	case EXTZV:	{		/* bit tests:		**	extv	A,$1,B,rC  \		**	tstl	rC	    >	jbc	A,B,D		**	jeql	D	   /		**		** also byte- and word-size fields:		**	extv	$n*8,$8,A,B	>	cvtbl	n+A,B		**	extv	$n*16,$16,A,B	>	cvtwl	n+A,B		**	extzv	$n*8,$8,A,B	>	movzbl	n+A,B		**	extzv	$n*16,$16,A,B	>	movzwl	n+A,B		*/		register struct	node	*pf;	/* forward node */		register struct	node	*pn;	/* next node (after pf) */		int	flen;			/* field length */		splitrand(p);		if (regs[RT2][0] != '$') goto std;		if ((flen = getnum(&regs[RT2][1])) < 0) goto std;		if (flen == 1)		{			register int	extreg;		/* reg extracted to */			extreg = isreg(regs[RT4]);			if (extreg < 0 || extreg >= NUSE) goto std;			if ((pf = p->forw)->op != TST) goto std;			if (uses[extreg] && uses[extreg] != pf) goto std;			splitrand(pf);			if (extreg != isreg(regs[RT1])) goto std;			if ((pn = pf->forw)->op != CBR) goto std;			if (pn->subop != JEQ && pn->subop != JNE) goto std;			delnode(p); delnode(pf);			pn->subop = (pn->subop == JEQ) ? JBC : JBS;			for(cp2=p->code; *cp2++!=',';);			for(cp1=cp2;     *cp1++!=',';);			while (*cp1!=',') *cp2++= *cp1++; *cp2='\0';			pn->code = p->code; pn->pop = NULL;			uses[extreg] = NULL;		}		else		if (flen == 8 || flen == 16)		{			register int	boff;	/* bit offset */			register int	coff;	/* chunk (byte or word) offset*/			if (regs[RT1][0] != '$') goto std;			if ((boff = getnum(&regs[RT1][1])) < 0) goto std;			coff = boff / flen;			if (coff && (isreg(regs[RT3]) >= 0)) goto std;			if (boff < 0 || (boff % flen) != 0) goto std;			p->op = (p->op == EXTV) ? CVT : MOVZ;			p->subop = U((flen == 8 ? BYTE : WORD), LONG);			if (coff == 0)				strcpy(regs[RT1], regs[RT3]);			else				sprintf(regs[RT1], "%d%s%s", coff, regs[RT3][0]=='(' ? "":"+",					regs[RT3]);			strcpy(regs[RT2], regs[RT4]);			regs[RT3][0] = '\0'; regs[RT4][0] = '\0';			p->pop = 0; newcode(p);		}		nchange++;		goto std;	}	case CMP:	{		/* comparison to -63 to -1:		**	cmpl	r0,$-1	>	incl	r0		**	jeql	...		**		**	cmpl	r0,$-63	>	addl2	$63,r0		**	jeql	...		*/		register int	num;		register int	reg;		register struct	node	*regp = p->back;		if (p->forw->op != CBR) goto std;		if (p->forw->subop != JEQ && p->forw->subop != JNE) goto std;		splitrand(p);		if (strncmp(regs[RT2], "$-", 2) != 0) goto std;		reg = r = isreg(regs[RT1]);		if (r < 0) goto std;		if (r < NUSE && uses[r] != 0) goto std;		if (r >= NUSE && regp->op == MOV && p->subop == regp->subop)		{			if (*regp->code != 'r') goto std;			reg = regp->code[1] - '0';			if (isdigit(regp->code[2]) || reg >= NUSE || uses[reg])				goto std;		}		if (r >= NUSE) goto std;		if (reg != r)			sprintf(regs[RT1], "r%d", reg);		if ((num = getnum(&regs[RT2][2])) <= 0 || num > 63) goto std;		if (num == 1)		{			p->op = INC; regs[RT2][0] = '\0';		}		else		{			register char	*t;			t=regs[RT1];regs[RT1]=regs[RT2];regs[RT2]=t;			p->op = ADD; p->subop = U(p->subop, OP2);			for (t = &regs[RT1][2]; t[-1] = *t; t++) ;		}		p->pop = 0; newcode(p);		nchange++;		goto std;	}	case JSB:		if (equstr(p->code,"mcount")) {uses[0]=p; regs[0][0]= -1;}		goto std;	case JBR: case JMP:		clearuse();		if (p->subop==RET || p->subop==RSB) {uses[0]=p; regs[0][0]= -1; break;}		if (p->ref==0) goto std;	/* jmp (r0) */		/* fall through */	case CBR:		if (p->ref->ref!=0) for (r=NUSE;--r>=0;)			if (biti[r] & (int)p->ref->ref) {uses[r]=p; regs[r][0]= -1;}	case EROU: case JSW:	case TEXT: case DATA: case BSS: case ALIGN: case WGEN: case END: ;	}	}	for (p= &first; p!=0; p=p->forw)		if (p->op==LABEL || p->op==DLABEL) p->ref=0;	/* erase our tracks */}rmove(){	register struct node *p, *lastp;	register int r;	int r1;	clearreg();	for (p=first.forw; p!=0; p = p->forw) {	lastp=p;	if (debug) {		printf("Regs:\n");		for (r=0; r<NREG; r++)			if (regs[r][0]) {				r1=regs[r][0];				printf("%d: %d%d %s\n", r, r1&0xF, r1>>4, regs[r]+1);			}		printf("-\n");	}	switch (p->op) {	case CVT:		splitrand(p); goto mov;	case MOV:		splitrand(p);		if ((r = findrand(regs[RT1],p->subop)) >= 0) {			if (r == isreg(regs[RT2]) && p->forw->op!=CBR) {				delnode(p); redunm++; break;			}		}mov:		repladdr(p);		r = isreg(regs[RT1]);		r1 = isreg(regs[RT2]);		dest(regs[RT2],p->subop);		if (r>=0) {			if (r1>=0) savereg(r1, regs[r]+1, p->subop);			else if (p->op!=CVT) savereg(r, regs[RT2], p->subop);		} else if (r1>=0) savereg(r1, regs[RT1], p->subop);		else if (p->op!=CVT) setcon(regs[RT1], regs[RT2], p->subop);		break;/* .rx,.wx */	case MFPR:	case COM:	case NEG:/* .rx,.wx or .rx,.rx,.wx */	case ADD:	case SUB:	case BIC:	case BIS:	case XOR:	case MUL:	case DIV:	case ASH:	case MOVZ:/* .rx,.rx,.rx,.wx */	case EXTV:	case EXTZV:	case INSV:		splitrand(p);		repladdr(p);		dest(lastrand,p->subop);		if (p->op==INSV) ccloc[0]=0;		break;/* .mx or .wx */	case CLR:

⌨️ 快捷键说明

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