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

📄 local.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
# include "mfile1"/*	this file contains code which is dependent on the target machine */NODE *cast( p, t ) register NODE *p; TWORD t; {	/* cast node p to type t */	p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p );	p->left->op = FREE;	p->op = FREE;	return( p->right );	}NODE *clocal(p) NODE *p; {	/* this is called to do local transformations on	   an expression tree preparitory to its being	   written out in intermediate code.	*/	/* the major essential job is rewriting the	   automatic variables and arguments in terms of	   REG and OREG nodes */	/* conversion ops which are not necessary are also clobbered here */	/* in addition, any special features (such as rewriting	   exclusive or) are easily handled here as well */	register struct symtab *q;	register NODE *r;	register o;	register m, ml;	switch( o = p->op ){	case NAME:		if( p->rval < 0 ) { /* already processed; ignore... */			return(p);			}		q = &stab[p->rval];		switch( q->sclass ){		case AUTO:		case PARAM:			/* fake up a structure reference */			r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );			r->lval = 0;			r->rval = (q->sclass==AUTO?STKREG:ARGREG);			p = stref( block( STREF, r, p, 0, 0, 0 ) );			break;		case ULABEL:		case LABEL:		case STATIC:			if( q->slevel == 0 ) break;			p->lval = 0;			p->rval = -q->offset;			break;		case REGISTER:			p->op = REG;			p->lval = 0;			p->rval = q->offset;			break;			}		break;	case LT:	case LE:	case GT:	case GE:		if( ISPTR( p->left->type ) || ISPTR( p->right->type ) ){			p->op += (ULT-LT);			}		break;	case PCONV:		/* do pointer conversions for char and longs */		ml = p->left->type;		if( ( ml==CHAR || ml==UCHAR || ml==LONG || ml==ULONG ) && p->left->op != ICON ) break;		/* pointers all have the same representation; the type is inherited */		p->left->type = p->type;		p->left->cdim = p->cdim;		p->left->csiz = p->csiz;		p->op = FREE;		return( p->left );	case SCONV:		m = (p->type == FLOAT || p->type == DOUBLE );		ml = (p->left->type == FLOAT || p->left->type == DOUBLE );		if( m != ml ) break;		/* now, look for conversions downwards */		m = p->type;		ml = p->left->type;		if( p->left->op == ICON ){ /* simulate the conversion here */			CONSZ val;			val = p->left->lval;			switch( m ){			case CHAR:				p->left->lval = (char) val;				break;			case UCHAR:				p->left->lval = val & 0XFF;				break;			case UNSIGNED:				p->left->lval = val & 0XFFFFL;				break;			case INT:				p->left->lval = (int)val;				break;				}			p->left->type = m;			}		else {			/* meaningful ones are conversion of int to char, int to short,			   and short to char, and unsigned version of them */			if( m==CHAR || m==UCHAR ){				if( ml==LONG || ml==ULONG ) break;				}			else if( m==INT || m==UNSIGNED ){				if( ml==LONG || ml==ULONG ) break;				}			else if( m==LONG || m==ULONG ){				if( ml!=LONG && ml!= ULONG ) break;				}			}		/* clobber conversion */		p->op = FREE;		return( p->left );  /* conversion gets clobbered */	case ASSIGN:		/* get rid of SCONV for assignments		   from LONG -> CHAR|INT	*/		if( p->right->op == SCONV ) {			m = p->right->type;			ml = p->right->left->type;			if( ( m==LONG || m==ULONG ) &&			    ml!=FLOAT && ml!=DOUBLE ) {				p->right->op = FREE;				p->right = p->right->left;				}			}		break;	case PVCONV:	case PMCONV:		if( p->right->op != ICON ) cerror( "bad conversion", 0);		p->op = FREE;		return( buildtree( o==PMCONV?MUL:DIV, p->left, p->right ) );	case PLUS:	case MINUS:	case LS:	case MUL:		/* optimize address calculations with long indexes */		if( ISPTR( p->type ) || ISARY( p->type ) ) {			if( p->left->type==LONG || p->left->type==ULONG )				p->left = cast( p->left, INT );			if( p->right->type==LONG || p->right->type==ULONG )				p->right = cast( p->right, INT );			}		break;		}	return(p);	}andable( p ) NODE *p; {	return(1);  /* all names can have & taken on them */	}cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */	autooff = AUTOINIT;	}cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */	if( t==INT || t==UNSIGNED || ISPTR(t) ) return(1);	return(0);	}NODE *offcon( off, t, d, s ) OFFSZ off; TWORD t; {	/* return a node, for structure references, which is suitable for	   being added to a pointer of type t, in order to be off bits offset	   into a structure */	register NODE *p;	/* t, d, and s are the type, dimension offset, and sizeoffset */	/* in general they  are necessary for offcon, but not on H'well */	p = bcon(0);	p->lval = off/SZCHAR;	return(p);	}static inwd	/* current bit offsed in word */;static word	/* word being built from fields */;incode( p, sz ) register NODE *p; {	/* generate initialization code for assigning a constant c		to a field of width sz */	/* we assume that the proper alignment has been obtained */	/* inoff is updated to have the proper final value */	/* we also assume sz  < SZINT */	if((sz+inwd) > SZINT) cerror("incode: field > int");	word |= p->lval<<inwd;	inwd += sz;	inoff += sz;	if(inoff%SZINT == 0) {		printf( "	%o\n", word);		word = inwd = 0;		}	}fincode( d, sz ) double d; {	/* output code to initialize space of size sz to the value d */	/* the proper alignment has been obtained */	/* inoff is updated to have the proper final value */	/* on the target machine, write it out in octal! */	register int *mi = (int *)&d;	if( sz==SZDOUBLE )		printf( "	%o; %o; %o; %o\n", mi[0], mi[1], mi[2], mi[3] );	else		printf( "	%o; %o\n", mi[0], mi[1] );	inoff += sz;	}cinit( p, sz ) NODE *p; {	/* arrange for the initialization of p into a space of	size sz */	/* the proper alignment has been opbtained */	/* inoff is updated to have the proper final value */	ecode( p );	inoff += sz;	}vfdzero( n ){ /* define n bits of zeros in a vfd */	if( n <= 0 ) return;	inwd += n;	inoff += n;	if( inoff%ALINT ==0 ) {		printf( "	%o\n", word );		word = inwd = 0;		}	}char *exname( p ) char *p; {	/* make a name look like an external name in the local machine */	static char text[NCHNAM+1];	register i;	text[0] = '_';	for( i=1; *p&&i<NCHNAM; ++i ){		text[i] = *p++;		}	text[i] = '\0';	text[NCHNAM] = '\0';  /* truncate */	return( text );	}ctype( type ) TWORD type; { /* map types which are not defined on the local machine */	switch( BTYPE(type) ){	case SHORT:		MODTYPE(type,INT);		break;	case USHORT:		MODTYPE(type,UNSIGNED);		}	return( type );	}noinit() { /* curid is a variable which is defined but	is not initialized (and not a function );	This routine returns the stroage class for an uninitialized declaration */	return(EXTERN);	}commdec( id ){ /* make a common declaration for id, if reasonable */	register struct symtab *q;	OFFSZ off;	q = &stab[id];	printf( "	.comm	%s,", exname( q->sname ) );	off = tsize( q->stype, q->dimoff, q->sizoff );	printf( CONFMT, off/SZCHAR );	printf( ".\n" );	}isitlong( cb, ce ){ /* is lastcon to be long or short */	/* cb is the first character of the representation, ce the last */	if( ce == 'l' || ce == 'L' ||		lastcon >= (1L << (SZINT-1) ) ) return (1);	return(0);	}isitfloat( s ) char *s; {	double atof();	dcon = atof(s);	return( FCON );	}ecode( p ) NODE *p; {	/* walk the tree and write out the nodes.. */	if( nerrors ) return;	p2tree( p );	p2compile( p );	}

⌨️ 快捷键说明

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