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

📄 reader.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		p->in.right = NIL;	case CALL:		o = p->in.op = UNARY CALL;		if( gencall( p, cookie ) ) goto nomat;		goto cleanup;	case UNARY STCALL:		p->in.right = NIL;	case STCALL:		o = p->in.op = UNARY STCALL;		if( genscall( p, cookie ) ) goto nomat;		goto cleanup;		/* if arguments are passed in register, care must be taken that reclaim		/* not throw away the register which now has the result... */	case UNARY MUL:		if( cook == FOREFF ){			/* do nothing */			order( p->in.left, FOREFF );			p->in.op = FREE;			return;			}		offstar( p->in.left, cook );		goto again;	case INCR:  /* INCR and DECR */		if( setincr(p, cook) ) goto again;		/* x++ becomes (x += 1) -1; */		if( cook & FOREFF ){  /* result not needed so inc or dec and be done with it */			/* x++ => x += 1 */			p->in.op = (p->in.op==INCR)?ASG PLUS:ASG MINUS;			goto again;			}		p1 = tcopy(p);		reclaim( p->in.left, RNULL, 0 );		p->in.left = p1;		p1->in.op = (p->in.op==INCR)?ASG PLUS:ASG MINUS;		p->in.op = (p->in.op==INCR)?MINUS:PLUS;		goto again;	case STASG:		if( setstr( p, cook ) ) goto again;		goto nomat;	case ASG PLUS:  /* and other assignment ops */		if( setasop(p, cook) ) goto again;		/* there are assumed to be no side effects in LHS */		p2 = tcopy(p);		p->in.op = ASSIGN;		reclaim( p->in.right, RNULL, 0 );		p->in.right = p2;		canon(p);		rallo( p, p->in.rall );# ifndef BUG4		if( odebug ) fwalk( p, eprint, 0 );# endif		order( p2->in.left, INTBREG|INTAREG );		order( p2, INTBREG|INTAREG );		goto again;	case ASSIGN:		if( setasg( p, cook ) ) goto again;		goto nomat;	case BITYPE:		if( setbin( p, cook ) ) goto again;		/* try to replace binary ops by =ops */		switch(o){		case PLUS:		case MINUS:		case MUL:		case DIV:		case MOD:		case AND:		case OR:		case ER:		case LS:		case RS:			p->in.op = ASG o;			goto again;			}		goto nomat;		}	cleanup:	/* if it is not yet in the right state, put it there */	if( cook & FOREFF ){		reclaim( p, RNULL, 0 );		return;		}	if( p->in.op==FREE ) return;	if( tshape( p, cook ) ) return;	if( (m=match(p,cook) ) == MDONE ) return;	/* we are in bad shape, try one last chance */	if( lastchance( p, cook ) ) goto again;	goto nomat;	}int callflag;int fregs;store( p ) register NODE *p; {	/* find a subtree of p which should be stored */	register o, ty;	o = p->in.op;	ty = optype(o);	if( ty == LTYPE ) return;	switch( o ){	case UNARY CALL:	case UNARY FORTCALL:	case UNARY STCALL:		++callflag;		break;	case UNARY MUL:		if( asgop(p->in.left->in.op) ) stoasg( p->in.left, UNARY MUL );		break;	case CALL:	case FORTCALL:	case STCALL:		store( p->in.left );		stoarg( p->in.right, o );		++callflag;		return;	case COMOP:		markcall( p->in.right );		if( p->in.right->in.su > fregs ) SETSTO( p, INTEMP );		store( p->in.left );		return;	case ANDAND:	case OROR:	case QUEST:		markcall( p->in.right );		if( p->in.right->in.su > fregs ) SETSTO( p, INTEMP );	case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */	case NOT:		constore( p->in.left );		return;		}	if( ty == UTYPE ){		store( p->in.left );		return;		}	if( asgop( p->in.right->in.op ) ) stoasg( p->in.right, o );	if( p->in.su>fregs ){ /* must store */		mkadrs( p );  /* set up stotree and stocook to subtree				 that must be stored */		}	store( p->in.right );	store( p->in.left );	}constore( p ) register NODE *p; {	/* store conditional expressions */	/* the point is, avoid storing expressions in conditional	   conditional context, since the evaluation order is predetermined */	switch( p->in.op ) {	case ANDAND:	case OROR:	case QUEST:		markcall( p->in.right );	case NOT:		constore( p->in.left );		return;		}	store( p );	}markcall( p ) register NODE *p; {  /* mark off calls below the current node */	again:	switch( p->in.op ){	case UNARY CALL:	case UNARY STCALL:	case UNARY FORTCALL:	case CALL:	case STCALL:	case FORTCALL:		++callflag;		return;		}	switch( optype( p->in.op ) ){	case BITYPE:		markcall( p->in.right );	case UTYPE:		p = p->in.left;		/* eliminate recursion (aren't I clever...) */		goto again;	case LTYPE:		return;		}	}stoarg( p, calltype ) register NODE *p; {	/* arrange to store the args */	if( p->in.op == CM ){		stoarg( p->in.left, calltype );		p = p->in.right ;		}	if( calltype == CALL ){		STOARG(p);		}	else if( calltype == STCALL ){		STOSTARG(p);		}	else {		STOFARG(p);		}	callflag = 0;	store(p);# ifndef NESTCALLS	if( callflag ){ /* prevent two calls from being active at once  */		SETSTO(p,INTEMP);		store(p); /* do again to preserve bottom up nature....  */		}#endif	}int negrel[] = { NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE } ;  /* negatives of relationals */cbranch( p, true, false ) NODE *p; {	/* evaluate p for truth value, and branch to true or false	/* accordingly: label <0 means fall through */	register o, lab, flab, tlab;	lab = -1;	switch( o=p->in.op ){	case ULE:	case ULT:	case UGE:	case UGT:	case EQ:	case NE:	case LE:	case LT:	case GE:	case GT:		if( true < 0 ){			o = p->in.op = negrel[ o-EQ ];			true = false;			false = -1;			}#ifndef NOOPT		if( p->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->in.name[0] == '\0' ){			switch( o ){			case UGT:			case ULE:				o = p->in.op = (o==UGT)?NE:EQ;			case EQ:			case NE:			case LE:			case LT:			case GE:			case GT:				if( logop(p->in.left->in.op) ){					/* strange situation: e.g., (a!=0) == 0 */					/* must prevent reference to p->in.left->lable, so get 0/1 */					/* we could optimize, but why bother */					codgen( p->in.left, INAREG|INBREG );					}				codgen( p->in.left, FORCC );				cbgen( o, true, 'I' );				break;			case UGE:				codgen(p->in.left, FORCC);				cbgen( 0, true, 'I' );  /* unconditional branch */				break;			case ULT:				codgen(p->in.left, FORCC);				}			}		else#endif			{			p->bn.label = true;			codgen( p, FORCC );			}		if( false>=0 ) cbgen( 0, false, 'I' );		reclaim( p, RNULL, 0 );		return;	case ANDAND:		lab = false<0 ? getlab() : false ;		cbranch( p->in.left, -1, lab );		cbranch( p->in.right, true, false );		if( false < 0 ) deflab( lab );		p->in.op = FREE;		return;	case OROR:		lab = true<0 ? getlab() : true;		cbranch( p->in.left, lab, -1 );		cbranch( p->in.right, true, false );		if( true < 0 ) deflab( lab );		p->in.op = FREE;		return;	case NOT:		cbranch( p->in.left, false, true );		p->in.op = FREE;		break;	case COMOP:		codgen( p->in.left, FOREFF );		p->in.op = FREE;		cbranch( p->in.right, true, false );		return;	case QUEST:		flab = false<0 ? getlab() : false;		tlab = true<0 ? getlab() : true;		cbranch( p->in.left, -1, lab = getlab() );		cbranch( p->in.right->in.left, tlab, flab );		deflab( lab );		cbranch( p->in.right->in.right, true, false );		if( true < 0 ) deflab( tlab);		if( false < 0 ) deflab( flab );		p->in.right->in.op = FREE;		p->in.op = FREE;		return;	case ICON:		if( p->in.type != FLOAT && p->in.type != DOUBLE ){			if( p->tn.lval || p->in.name[0] ){				/* addresses of C objects are never 0 */				if( true>=0 ) cbgen( 0, true, 'I' );				}			else if( false>=0 ) cbgen( 0, false, 'I' );			p->in.op = FREE;			return;			}		/* fall through to default with other strange constants */	default:		/* get condition codes */		codgen( p, FORCC );		if( true >= 0 ) cbgen( NE, true, 'I' );		if( false >= 0 ) cbgen( true >= 0 ? 0 : EQ, false, 'I' );		reclaim( p, RNULL, 0 );		return;		}	}rcount(){ /* count recursions */	if( ++nrecur > NRECUR ){		cerror( "expression causes compiler loop: try simplifying" );		}	}# ifndef BUG4eprint( p, down, a, b ) NODE *p; int *a, *b; {	*a = *b = down+1;	while( down >= 2 ){		printf( "\t" );		down -= 2;		}	if( down-- ) printf( "    " );	printf( "%o) %s", p, opst[p->in.op] );	switch( p->in.op ) { /* special cases */	case REG:		printf( " %s", rnames[p->tn.rval] );		break;	case ICON:	case NAME:	case OREG:		printf( " " );		adrput( p );		break;	case STCALL:	case UNARY STCALL:	case STARG:	case STASG:		printf( " size=%d", p->stn.stsize );		printf( " align=%d", p->stn.stalign );		break;		}	printf( ", " );	tprint( p->in.type );	printf( ", " );	if( p->in.rall == NOPREF ) printf( "NOPREF" );	else {		if( p->in.rall & MUSTDO ) printf( "MUSTDO " );		else printf( "PREF " );		printf( "%s", rnames[p->in.rall&~MUSTDO]);		}	printf( ", SU= %d\n", p->in.su );	}# endif# ifndef NOMAINNODE *eread(){	/* call eread recursively to get subtrees, if any */	register NODE *p;	register i, c;	register char *pc;	register j;	i = rdin( 10 );	p = talloc();	p->in.op = i;	i = optype(i);	if( i == LTYPE ) p->tn.lval = rdin( 10 );	if( i != BITYPE ) p->tn.rval = rdin( 10 );	p->in.type = rdin(8 );	p->in.rall = NOPREF;  /* register allocation information */	if( p->in.op == STASG || p->in.op == STARG || p->in.op == STCALL || p->in.op == UNARY STCALL ){		p->stn.stsize = (rdin( 10 ) + (SZCHAR-1) )/SZCHAR;		p->stn.stalign = rdin(10) / SZCHAR;		if( getchar() != '\n' ) cerror( "illegal \n" );		}	else {   /* usual case */		if( p->in.op == REG ) rbusy( p->tn.rval, p->in.type );  /* non usually, but sometimes justified */#ifndef FLEXNAMES		for( pc=p->in.name,j=0; ( c = getchar() ) != '\n'; ++j ){			if( j < NCHNAM ) *pc++ = c;			}		if( j < NCHNAM ) *pc = '\0';#else		{ char buf[BUFSIZ];		for( pc=buf,j=0; ( c = getchar() ) != '\n'; ++j ){			if( j < BUFSIZ ) *pc++ = c;			}		if( j < BUFSIZ ) *pc = '\0';		p->in.name = tstr(buf);		}#endif		}	/* now, recursively read descendents, if any */	if( i != LTYPE ) p->in.left = eread();	if( i == BITYPE ) p->in.right = eread();	return( p );	}CONSZrdin( base ){	register sign, c;	CONSZ val;	sign = 1;	val = 0;	while( (c=getchar()) > 0 ) {		if( c == '-' ){			if( val != 0 ) cerror( "illegal -");			sign = -sign;			continue;			}		if( c == '\t' ) break;		if( c>='0' && c<='9' ) {			val *= base;			if( sign > 0 )				val += c-'0';			else				val -= c-'0';			continue;			}		cerror( "illegal character `%c' on intermediate file", c );		break;		}	if( c <= 0 ) {		cerror( "unexpected EOF");		}	return( val );	}# endif#ifndef FIELDOPS	/* do this if there is no special hardware support for fields */ffld( p, down, down1, down2 ) NODE *p; int *down1, *down2; {	 /* look for fields that are not in an lvalue context, and rewrite them... */	register NODE *shp;	register s, o, v, ty;	*down1 =  asgop( p->in.op );	*down2 = 0;	if( !down && p->in.op == FLD ){ /* rewrite the node */		if( !rewfld(p) ) return;		ty = (szty(p->in.type) == 2)? LONG: INT;		v = p->tn.rval;		s = UPKFSZ(v);# ifdef RTOLBYTES		o = UPKFOFF(v);  /* amount to shift */# else		o = szty(p->in.type)*SZINT - s - UPKFOFF(v);  /* amount to shift */#endif		/* make & mask part */		p->in.left->in.type = ty;		p->in.op = AND;		p->in.right = talloc();		p->in.right->in.op = ICON;		p->in.right->in.rall = NOPREF;		p->in.right->in.type = ty;		p->in.right->tn.lval = 1;		p->in.right->tn.rval = 0;#ifndef FLEXNAMES		p->in.right->in.name[0] = '\0';#else		p->in.right->in.name = "";#endif		p->in.right->tn.lval <<= s;		p->in.right->tn.lval--;		/* now, if a shift is needed, do it */		if( o != 0 ){			shp = talloc();			shp->in.op = RS;			shp->in.rall = NOPREF;			shp->in.type = ty;			shp->in.left = p->in.left;			shp->in.right = talloc();			shp->in.right->in.op = ICON;			shp->in.right->in.rall = NOPREF;			shp->in.right->in.type = ty;			shp->in.right->tn.rval = 0;			shp->in.right->tn.lval = o;  /* amount to shift */#ifndef FLEXNAMES			shp->in.right->in.name[0] = '\0';#else			shp->in.right->in.name = "";#endif			p->in.left = shp;			/* whew! */			}		}	}#endiforeg2( p ) register NODE *p; {	/* look for situations where we can turn * into OREG */	NODE *q;	register i;	register r;	register char *cp;	register NODE *ql, *qr;	CONSZ temp;	if( p->in.op == UNARY MUL ){		q = p->in.left;		if( q->in.op == REG ){			temp = q->tn.lval;			r = q->tn.rval;			cp = q->in.name;			goto ormake;			}		if( q->in.op != PLUS && q->in.op != MINUS ) return;		ql = q->in.left;		qr = q->in.right;#ifdef R2REGS		/* look for doubly indexed expressions */		if( q->in.op == PLUS) {			if( (r=base(ql))>=0 && (i=offset(qr, tlen(p)))>=0) {				makeor2(p, ql, r, i);				return;			} else if( (r=base(qr))>=0 && (i=offset(ql, tlen(p)))>=0) {				makeor2(p, qr, r, i);				return;				}			}#endif		if( (q->in.op==PLUS || q->in.op==MINUS) && qr->in.op == ICON &&				ql->in.op==REG && szty(qr->in.type)==1) {			temp = qr->tn.lval;			if( q->in.op == MINUS ) temp = -temp;			r = ql->tn.rval;			temp += ql->tn.lval;			cp = qr->in.name;			if( *cp && ( q->in.op == MINUS || *ql->in.name ) ) return;			if( !*cp ) cp = ql->in.name;			ormake:			if( notoff( p->in.type, r, temp, cp ) ) return;			p->in.op = OREG;			p->tn.rval = r;			p->tn.lval = temp;#ifndef FLEXNAMES			for( i=0; i<NCHNAM; ++i )				p->in.name[i] = *cp++;#else			p->in.name = cp;#endif			tfree(q);			return;			}		}	}canon(p) NODE *p; {	/* put p in canonical form */	int oreg2(), sucomp();#ifndef FIELDOPS	int ffld();	fwalk( p, ffld, 0 ); /* look for field operators */# endif	walkf( p, oreg2 );  /* look for and create OREG nodes */#ifdef MYCANON	MYCANON(p);  /* your own canonicalization routine(s) */#endif	walkf( p, sucomp );  /* do the Sethi-Ullman computation */	}

⌨️ 快捷键说明

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