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

📄 c21.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)c21.c	4.1	ULTRIX	7/3/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984-1989 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *                     Modification History                             * *									* * 0008 Jon Reeves, 01-Mar-1989						* *	Change dest() to invalidate wild stores sooner; fixed		* *	bypass of test when it immediately followed a store to -n(fp)	* *	(Change from 4.3 code.)						* *									* * 0007 David L Ballenger, 10-Jun-1986					* *	Fix bug in redunbr() which didn't completely update the	label	* *	information when changing a branch to go to a new label.	* *	This could cause the branch to go to an undefined label.	* *									* * 0006	David L Ballenger, 02-Mar-1986					* *	Do further corrections on the bitopt() routine fixed previously	* *	do correctly distinguish when bixx operations can be optimized. * *	The previous fix introduced problems with index mode.		* *									* * 0005	David L Ballenger, 24-Feb-1986					* *	Fix problem reported by SPR ICA-679 in which a bitb was		* *	incorrectly being converted to jlbc.  Also fix problem		* *	found in the QVSS driver in which a jbs/jbc was incorrectly	* *	converted into a jbss/jbcc.					* *									* *	David L. Ballenger, 06-Nov-1984					* * 0004 Modify byondrd() to handle MFPR instructions correctly, i.e.	* *	to recognize that it is a 2 operand instruction.		* *									* * 	David L. Ballenger, 10-Oct-1984					* * 0003 Modify compat() so that GFLOAT, HFLOAT, and OCTA types are	* *	handled correctly, specifically so that GFLOAT and FFLOAT are	* *	correctly determined to be different types.			* *                                                                      * *	David L. Ballenger, 19-Jul-1984					* * 0002 Fix problems in bicopt with optimizing BICL and preceding	* *	instructions.							* *	- don't allow a CVT of a float type preceding a BICL to be	* *	  deleted.							* *	- don't allow a CVT or MOVZ with an auto(in|de)cremented source * *	  to be delete unless the source of the instruction replacing	* *	  it is the same size.						* *	- don't replace a BICL with an EXTZV unless a preceding ASHL	* *	  and/or CVT/MOVZ was deleted.					* *									* *	David L. Ballenger, 24-May-1984					* * 0001	Fix problems with converting EXT[Z]V instructions to CVT{B|W}L	* *	or MOVZ{B|W}L instructions.  An extract with a bit offset of 16	* *	and length 16 was not being converted with the proper alignment.* *	Also an extract with an offset of 8 and length 16 was not being	* *	converted at all.						* *                                                                      * ************************************************************************//* * C object code improver-- second part */#include "c2.h"#include <stdio.h>#include <ctype.h>#include <varargs.h>#include <strings.h>#define NUSE 6#define BITS_PER_UNIT 8		/* The bits per addressable unit is used to				 * calculate the addressable unit offset				 * for converting EXT instructions to CVT				 * or MOVZ instructions.    		0001				 */int ioflag;int biti[NUSE] = {1,2,4,8,16,32};int bitsize[] = {	/* index by type codes */	0,		/* 0	not allocated */	8,		/* 1	BYTE */	16,		/* 2	WORD */	32,		/* 3	LONG */	32,		/* 4	FFLOAT */	64,		/* 5	DFLOAT */	64,		/* 6	QUAD */	0,		/* 7	OP2 */	0,		/* 8	OP3 */	0,		/* 9	OPB */	0,		/* 10	OPX */	64,		/* 11	GFLOAT */	128,		/* 12	HFLOAT */	128		/* 13	OCTA */};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();/* new_operands * * Routine to reformat the new operands when an instruction or instruction * sequence is optimized.  Accepts a variable list of 2 or more arguments. * The first argument is the pointer to the node which is getting the new * operands, the second argument is the format string and the rest of the * arguments are as specified in the format string as in printf(). * */static voidnew_operands(va_alist)	va_dcl{	va_list		args;	register struct node	*ptr;	char			*format;	char			operands[C2_ASIZE];	register int		n_chars;	va_start(args);	/*	 * Get the node pointer and format, then call vsprintf() with	 * the format and the remaining arguments.	 */	ptr = va_arg(args,struct node *);	format = va_arg(args,char *);	n_chars = vsprintf(operands,format,args);	if (n_chars > C2_ASIZE) {		fputs("c2: buffer overflow in new_operands()\n",stderr);		exit(1);	}	/* Allocate a buffer for the string, copy the new operands to it	 * and return a pointer to it.	 */	ptr->code = alloc(n_chars+1);	(void)strcpy(ptr->code,operands);}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)		{			/* If the extract is a byte or word length we may be			 * able to change it to a CVT or MOVZ instruction.			 */			register int	boff;	/* bit offset */			register int	coff;	/* chunk (byte or word) offset*/

⌨️ 快捷键说明

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