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

📄 reader.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)reader.c	1.6	(ULTRIX)	3/14/86";#endif lint# include "mfile2"/************************************************************************ *									* *			Copyright (c) 1983 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 * *	Lu Anne Van de Pas * 002	Added -f flag which specifies that f floating arithmetic be done *	in f and not to be promoted to d if it's not necessary.  Also added *	qdebug to print out the table entry that was matched. * *	Stephen Reilly, 21-Oct-83: * 001- New -M flag is added that will indicate which float instruction *	is required ( gfloat or dfloat). * ************************************************************************//*	some storage declarations */# ifndef ONEPASSNODE node[TREESZ];char filename[100] = "";  /* the name of the file */int ftnno;  /* number of current function */int lineno;# else# define NOMAIN#endifint nrecur;/* *	If Mflag is set it indicates that user wants gfloat instructions */int Mflag;							/* slr001 */int lflag;/* If fflag is set it indicates that the user doesn't want  * floating point operations converted up to double precision  */ extern int fflag; 					/* vdp002 */ 	extern int Wflag;int edebug = 0;int xdebug = 0;int udebug = 0;int vdebug = 0;int qdebug = 0;			/*vdp002  print out the code template				 matched */  OFFSZ tmpoff;  /* offset for first temporary, in bits for current block */OFFSZ maxoff;  /* maximum temporary offset over all blocks in current ftn, in bits */int maxtreg;NODE *stotree;int stocook;OFFSZ baseoff = 0;OFFSZ maxtemp = 0;p2init( argc, argv ) char *argv[];{	/* set the values of the pass 2 arguments */	register int c;	register char *cp;	register files;	allo0();  /* free all regs */	files = 0;	for( c=1; c<argc; ++c ){		if( *(cp=argv[c]) == '-' ){			while( *++cp ){				switch( *cp ){				case 'X':  /* pass1 flags */					while( *++cp ) { /* VOID */ }					--cp;					break;				case 'l':  /* linenos */					++lflag;					break;				case 'q':  /*vdp002 code template matched*/					++qdebug;					break;				case 'e':  /* expressions */					++edebug;					break;				case 'o':  /* orders */					++odebug;					break;				case 'r':  /* register allocation */					++rdebug;					break;				case 'a':  /* rallo */					++radebug;					break;				case 'v':					++vdebug;					break;				case 't':  /* ttype calls */					++tdebug;					break;				case 's':  /* shapes */					++sdebug;					break;				case 'u':  /* Sethi-Ullman testing (machine dependent) */					++udebug;					break;				case 'x':  /* general machine-dependent debugging flag */					++xdebug;					break;				case 'w':				case 'W':  /* shut up warnings */					++Wflag;					break;				case 'M':  /* slr001 gfloat instruction? */					++Mflag;		/* slr001 */					break;			/* slr001 */				case 'f':  /* vdp002 floating point arithmetic */					++fflag; 					break; 				default:					cerror( "bad option: %c", *cp );					}				}			}		else files = 1;  /* assumed to be a filename */		}	mkdope();	setrew();	return( files );	}# ifndef NOMAINunsigned int caloff();unsigned int offsz;mainp2( argc, argv ) char *argv[]; {	register files;	register temp;	register c;	register char *cp;	register NODE *p;	offsz = caloff();	files = p2init( argc, argv );	tinit();	reread:	if( files ){		while( files < argc && argv[files][0] == '-' ) {			++files;			}		if( files > argc ) return( nerrors );		freopen( argv[files], "r", stdin );		}	while( (c=getchar()) > 0 ) switch( c ){	case ')':	default:		/* copy line unchanged */		if ( c != ')' )			PUTCHAR( c );  /*  initial tab  */		while( (c=getchar()) > 0 ){			PUTCHAR(c);			if( c == '\n' ) break;			}		continue;	case BBEG:		/* beginning of a block */		temp = rdin(10);  /* ftnno */		tmpoff = baseoff = (unsigned int) rdin(10); /* autooff for block gives max offset of autos in block */		maxtreg = rdin(10);		if( getchar() != '\n' ) cerror( "intermediate file format error");		if( temp != ftnno ){ /* beginning of function */			maxoff = baseoff;			ftnno = temp;			maxtemp = 0;			}		else {			if( baseoff > maxoff ) maxoff = baseoff;			/* maxoff at end of ftn is max of autos and temps			   over all blocks in the function */			}		setregs();		continue;	case BEND:  /* end of block */		SETOFF( maxoff, ALSTACK );		eobl2();		while( (c=getchar()) != '\n' ){			if( c <= 0 ) cerror( "intermediate file format eof" );			}		continue;	case EXPR:		/* compile code for an expression */		lineno = rdin( 10 );		for( cp=filename; (*cp=getchar()) != '\n'; ++cp ) ; /* VOID, reads filename */		*cp = '\0';		if( lflag ) lineid( lineno, filename );		tmpoff = baseoff;  /* expression at top level reuses temps */		p = eread();# ifndef BUG4		if( edebug ) fwalk( p, eprint, 0 );# endif# ifdef MYREADER		MYREADER(p);  /* do your own laundering of the input */# endif		nrecur = 0;		delay( p );  /* expression statement  throws out results */		reclaim( p, RNULL, 0 );		allchk();		tcheck();		continue;	default:		cerror( "intermediate file format error" );		}	/* EOF */	if( files ) goto reread;	return(nerrors);	}# endif# ifdef ONEPASSp2compile( p ) NODE *p; {	if( lflag ) lineid( lineno, filename );	tmpoff = baseoff;  /* expression at top level reuses temps */	/* generate code for the tree p */# ifndef BUG4	if( edebug ) fwalk( p, eprint, 0 );# endif# ifdef MYREADER	MYREADER(p);  /* do your own laundering of the input */# endif	nrecur = 0;	delay( p );  /* do the code generation */	reclaim( p, RNULL, 0 );	allchk();	/* can't do tcheck here; some stuff (e.g., attributes) may be around from first pass */	/* first pass will do it... */	}p2bbeg( aoff, myreg ) {	static int myftn = -1;	tmpoff = baseoff = (unsigned int) aoff;	maxtreg = myreg;	if( myftn != ftnno ){ /* beginning of function */		maxoff = baseoff;		myftn = ftnno;		maxtemp = 0;		}	else {		if( baseoff > maxoff ) maxoff = baseoff;		/* maxoff at end of ftn is max of autos and temps over all blocks */		}	setregs();	}p2bend(){	SETOFF( maxoff, ALSTACK );	eobl2();	}# endifNODE *deltrees[DELAYS];int deli;delay( p ) register NODE *p; {	/* look in all legal places for COMOP's and ++ and -- ops to delay */	/* note; don't delay ++ and -- within calls or things like	/* getchar (in their macro forms) will start behaving strangely */	register i;	/* look for visible COMOPS, and rewrite repeatedly */	while( delay1( p ) ) { /* VOID */ }	/* look for visible, delayable ++ and -- */	deli = 0;	delay2( p );	codgen( p, FOREFF );  /* do what is left */	for( i = 0; i<deli; ++i ) codgen( deltrees[i], FOREFF );  /* do the rest */	}delay1( p ) register NODE *p; {  /* look for COMOPS */	register o, ty;	o = p->in.op;	ty = optype( o );	if( ty == LTYPE ) return( 0 );	else if( ty == UTYPE ) return( delay1( p->in.left ) );	switch( o ){	case QUEST:	case ANDAND:	case OROR:		/* don't look on RHS */		return( delay1(p->in.left ) );	case COMOP:  /* the meat of the routine */		delay( p->in.left );  /* completely evaluate the LHS */		/* rewrite the COMOP */		{ register NODE *q;			q = p->in.right;			ncopy( p, p->in.right );			q->in.op = FREE;			}		return( 1 );		}	return( delay1(p->in.left) || delay1(p->in.right ) );	}delay2( p ) register NODE *p; {	/* look for delayable ++ and -- operators */	register o, ty;	o = p->in.op;	ty = optype( o );	switch( o ){	case NOT:	case QUEST:	case ANDAND:	case OROR:	case CALL:	case UNARY CALL:	case STCALL:	case UNARY STCALL:	case FORTCALL:	case UNARY FORTCALL:	case COMOP:	case CBRANCH:		/* for the moment, don7t delay past a conditional context, or		/* inside of a call */		return;	case UNARY MUL:		/* if *p++, do not rewrite */		if( autoincr( p ) ) return;		break;	case INCR:	case DECR:		if( deltest( p ) ){			if( deli < DELAYS ){				register NODE *q;				deltrees[deli++] = tcopy(p);				q = p->in.left;				p->in.right->in.op = FREE;  /* zap constant */				ncopy( p, q );				q->in.op = FREE;				return;				}			}		}	if( ty == BITYPE ) delay2( p->in.right );	if( ty != LTYPE ) delay2( p->in.left );	}codgen( p, cookie ) NODE *p; {	/* generate the code for p;	   order may call codgen recursively */	/* cookie is used to describe the context */	for(;;){		canon(p);  /* creats OREG from * if possible and does sucomp */		stotree = NIL;# ifndef BUG4		if( edebug ){			printf( "store called on:\n" );			fwalk( p, eprint, 0 );			}# endif		store(p);		if( stotree==NIL ) break;		/* because it's minimal, can do w.o. stores */		order( stotree, stocook );		}	order( p, cookie );	}# ifndef BUG4char *cnames[] = {	"SANY",	"SAREG",	"STAREG",	"SBREG",	"STBREG",	"SCC",	"SNAME",	"SCON",	"SFLD",	"SOREG",# ifdef WCARD1	"WCARD1",# else	"STARNM",# endif# ifdef WCARD2"	"WCARD2",# else	"STARREG",# endif	"INTEMP",	"FORARG",	"SWADD",	0,	};extern prcook( cookie ){	/* print a nice-looking description of cookie */	int i, flag;	if( cookie & SPECIAL ){		if( cookie == SZERO ) printf( "SZERO" );		else if( cookie == SONE ) printf( "SONE" );		else if( cookie == SMONE ) printf( "SMONE" );		else printf( "SPECIAL+%d", cookie & ~SPECIAL );		return;		}	flag = 0;	for( i=0; cnames[i]; ++i ){		if( cookie & (1<<i) ){			if( flag ) printf( "|" );			++flag;			printf( cnames[i] );			}		}	}# endifint odebug = 0;order(p,cook) NODE *p; {	register o, ty, m;	int m1;	int cookie;	NODE *p1, *p2;	cookie = cook;	rcount();	canon(p);	rallo( p, p->in.rall );	goto first;	/* by this time, p should be able to be generated without stores;	   the only question is how */	again:	if ( p->in.op == FREE )		return;		/* whole tree was done */	cookie = cook;	rcount();	canon(p);	rallo( p, p->in.rall );	/* if any rewriting and canonicalization has put	 * the tree (p) into a shape that cook is happy	 * with (exclusive of FOREFF, FORREW, and INTEMP)	 * then we are done.	 * this allows us to call order with shapes in	 * addition to cookies and stop short if possible.	 */	if( tshape(p, cook &(~(FOREFF|FORREW|INTEMP))) )return;	first:# ifndef BUG4	if( odebug ){		printf( "order( %o, ", p );		prcook( cookie );		printf( " )\n" );		fwalk( p, eprint, 0 );		}# endif	o = p->in.op;	ty = optype(o);	/* first of all, for most ops, see if it is in the table */	/* look for ops */	switch( m = p->in.op ){	default:		/* look for op in table */		for(;;){			if( (m = match( p, cookie ) ) == MDONE ) goto cleanup;			else if( m == MNOPE ){				if( !(cookie = nextcook( p, cookie ) ) ) goto nomat;				continue;				}			else break;			}		break;	case COMOP:	case FORCE:	case CBRANCH:	case QUEST:	case ANDAND:	case OROR:	case NOT:	case UNARY CALL:	case CALL:	case UNARY STCALL:	case STCALL:	case UNARY FORTCALL:	case FORTCALL:		/* don't even go near the table... */		;		}	/* get here to do rewriting if no match or	   fall through from above for hard ops */	p1 = p->in.left;	if( ty == BITYPE ) p2 = p->in.right;	else p2 = NIL;	# ifndef BUG4	if( odebug ){		printf( "order( %o, ", p );		prcook( cook );		printf( " ), cookie " );		prcook( cookie );		printf( ", rewrite %s\n", opst[m] );		}# endif	switch( m ){	default:		nomat:		cerror( "no table entry for op %s", opst[p->in.op] );	case COMOP:		codgen( p1, FOREFF );		p2->in.rall = p->in.rall;		codgen( p2, cookie );		ncopy( p, p2 );		p2->in.op = FREE;		goto cleanup;	case FORCE:		/* recurse, letting the work be done by rallo */		p = p->in.left;		cook = INTAREG|INTBREG;		goto again;	case CBRANCH:		o = p2->tn.lval;		cbranch( p1, -1, o );		p2->in.op = FREE;		p->in.op = FREE;		return;	case QUEST:		cbranch( p1, -1, m=getlab() );		p2->in.left->in.rall = p->in.rall;		codgen( p2->in.left, INTAREG|INTBREG );		/* force right to compute result into same reg used by left */		p2->in.right->in.rall = p2->in.left->tn.rval|MUSTDO;		reclaim( p2->in.left, RNULL, 0 );		cbgen( 0, m1 = getlab(), 'I' );		deflab( m );		codgen( p2->in.right, INTAREG|INTBREG );		deflab( m1 );		p->in.op = REG;  /* set up node describing result */		p->tn.lval = 0;		p->tn.rval = p2->in.right->tn.rval;		p->in.type = p2->in.right->in.type;		tfree( p2->in.right );		p2->in.op = FREE;		goto cleanup;	case ANDAND:	case OROR:	case NOT:  /* logical operators */		/* if here, must be a logical operator for 0-1 value */		cbranch( p, -1, m=getlab() );		p->in.op = CCODES;		p->bn.label = m;		order( p, INTAREG );		goto cleanup;	case FLD:	/* fields of funny type */		if ( p1->in.op == UNARY MUL ){			offstar( p1->in.left, cook );			goto again;			}	case UNARY MINUS:		order( p1, INBREG|INAREG );		goto again;	case NAME:		/* all leaves end up here ... */		if( o == REG ) goto nomat;		order( p, INTAREG|INTBREG );		goto again;	case INIT:		uerror( "illegal initialization" );		return;	case UNARY FORTCALL:		p->in.right = NIL;	case FORTCALL:		o = p->in.op = UNARY FORTCALL;		if( genfcall( p, cookie ) ) goto nomat;		goto cleanup;	case UNARY CALL:

⌨️ 快捷键说明

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