local.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 464 行

C
464
字号
#ifndef lintstatic char	*sccsid = " @(#)local.c	4.1	(ULTRIX)	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 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**	David Metsky		14-Jan-86** 001	Added from BSD 4.3 version as part of upgrade.**	Based on:	local.c		1.8		8/23/85**************************************************************************/# include "pass1.h"/*	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->in.left->in.op = FREE;	p->in.op = FREE;	return( p->in.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->in.op ){	case NAME:		if( p->tn.rval < 0 ) { /* already processed; ignore... */			return(p);			}		q = &stab[p->tn.rval];		switch( q->sclass ){		case AUTO:		case PARAM:			/* fake up a structure reference */			r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );			r->tn.lval = 0;			r->tn.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->tn.lval = 0;			p->tn.rval = -q->offset;			break;		case REGISTER:			p->in.op = REG;			p->tn.lval = 0;			p->tn.rval = q->offset;			break;			}		break;	case PCONV:		/* do pointer conversions for char and longs */		ml = p->in.left->in.type;		if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ) break;		/* pointers all have the same representation; the type is inherited */		p->in.left->in.type = p->in.type;		p->in.left->fn.cdim = p->fn.cdim;		p->in.left->fn.csiz = p->fn.csiz;		p->in.op = FREE;		return( p->in.left );	case SCONV:		m = (p->in.type == FLOAT || p->in.type == DOUBLE );		ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE );		o = p->in.left->in.op;		if( (o == FCON || o == DCON) && ml && !m ) {			/* float type to int type */			r = block( ICON, (NODE *)NULL, (NODE *)NULL, INT, 0, 0 );			if( o == FCON )				r->tn.lval = (int) p->in.left->fpn.fval;			else				r->tn.lval = (int) p->in.left->dpn.dval;			r->tn.rval = NONAME;			p->in.left->in.op = FREE;			p->in.left = r;			}		else#ifdef SPRECC			if ( ml || m )#else			if ( ml != m )#endif				break;		/* now, look for conversions downwards */		m = p->in.type;		ml = p->in.left->in.type;		if( p->in.left->in.op == ICON ){ /* simulate the conversion here */			CONSZ val;			val = p->in.left->tn.lval;			switch( m ){			case CHAR:				p->in.left->tn.lval = (char) val;				break;			case UCHAR:				p->in.left->tn.lval = val & 0XFF;				break;			case USHORT:				p->in.left->tn.lval = val & 0XFFFFL;				break;			case SHORT:				p->in.left->tn.lval = (short)val;				break;			case UNSIGNED:				p->in.left->tn.lval = val & 0xFFFFFFFFL;				break;			case INT:				p->in.left->tn.lval = (int)val;				break;				}			p->in.left->in.type = m;			}		else if( m != FLOAT && m != DOUBLE )			break;		/* clobber conversion */		p->in.op = FREE;		return( p->in.left );  /* conversion gets clobbered */	case PVCONV:	case PMCONV:		if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);		p->in.op = FREE;		return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );	case RS:	case ASG RS:		/* convert >> to << with negative shift count */		/* only if type of left operand is not unsigned */		if( ISUNSIGNED(p->in.left->in.type) ) break;		if( p->in.right->in.op != UNARY MINUS )			p->in.right = buildtree( UNARY MINUS, p->in.right, NIL );		else {			r = p->in.right;			p->in.right = p->in.right->in.left;			r->in.op = FREE;		}		if( p->in.op == RS ) p->in.op = LS;		else p->in.op = ASG LS;		break;	case FLD:		/* make sure that the second pass does not make the		   descendant of a FLD operator into a doubly indexed OREG */		if( p->in.left->in.op == UNARY MUL				&& (r=p->in.left->in.left)->in.op == PCONV)			if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) 				if( ISPTR(r->in.type) ) {					if( ISUNSIGNED(p->in.left->in.type) )						p->in.left->in.type = UCHAR;					else						p->in.left->in.type = CHAR;				}		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 */#ifdef TRUST_REG_CHAR_AND_REG_SHORT	if( t==INT || t==UNSIGNED || t==LONG || t==ULONG	/* tbl */		|| t==CHAR || t==UCHAR || t==SHORT 		/* tbl */		|| t==USHORT || ISPTR(t)) return(1);		/* tbl */#else	if( t==INT || t==UNSIGNED || t==LONG || t==ULONG	/* wnj */#ifdef SPRECC		|| t==FLOAT#endif		|| ISPTR(t)) return (1);			/* wnj */#endif	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->tn.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 |= ((unsigned)(p->tn.lval<<(32-sz))) >> (32-sz-inwd);	inwd += sz;	inoff += sz;	if(inoff%SZINT == 0) {		printf( "	.long	0x%x\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! */	printf("	%s	0%c%.20e\n", sz == SZDOUBLE ? ".double" : ".float",		sz == SZDOUBLE ? 'd' : 'f', d);	inoff += sz;	}cinit( p, sz ) NODE *p; {	NODE *l;	/*	 * as a favor (?) to people who want to write	 *     int i = 9600/134.5;	 * we will, under the proper circumstances, do	 * a coersion here.	 */	switch (p->in.type) {	case INT:	case UNSIGNED:		l = p->in.left;		if (l->in.op != SCONV ||		    (l->in.left->tn.op != DCON && l->in.left->tn.op != FCON))			break;		l->in.op = FREE;		l = l->in.left;		l->tn.lval = l->tn.op == DCON ? (long)(l->dpn.dval) :			(long)(l->fpn.fval);		l->tn.rval = NONAME;		l->tn.op = ICON;		l->tn.type = INT;		p->in.left = l;		break;	}	/* 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( "	.long	0x%x\n", word );		word = inwd = 0;		}	}char *exname( p ) char *p; {	/* make a name look like an external name in the local machine */#ifndef FLEXNAMES	static char text[NCHNAM+1];#else	static char text[BUFSIZ+1];#endif	register i;	text[0] = '_';#ifndef FLEXNAMES	for( i=1; *p&&i<NCHNAM; ++i )#else	for( i=1; *p; ++i )#endif		text[i] = *p++;	text[i] = '\0';#ifndef FLEXNAMES	text[NCHNAM] = '\0';  /* truncate */#endif	return( text );	}ctype( type ) TWORD type;	{ /* map types which are not defined on the local machine */	switch( BTYPE(type) ){	case LONG:		MODTYPE(type,INT);		break;	case ULONG:		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, tsize();	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; {	union cvt {		double	d;		int	n[2];	} cvt;	double atof();	/* avoid floating point exception for double -> float conversions */	dcon = cvt.d = atof(s);	if( cvt.n[1] == 0 ){		fcon = dcon;		return( FCON );		}	return( DCON );	}ecode( p ) NODE *p; {	/* walk the tree and write out the nodes.. */	if( nerrors ) return;	p2tree( p );	p2compile( p );	}#ifndef ONEPASStlen(p) NODE *p; {	switch(p->in.type) {		case CHAR:		case UCHAR:			return(1);					case SHORT:		case USHORT:			return(2);					case DOUBLE:			return(8);					default:			return(4);		}	}#endif

⌨️ 快捷键说明

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