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

📄 code.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)code.c	1.2	(ULTRIX)	2/28/86";#endif lint/************************************************************************ *									* *			Copyright (c) 1985 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 * *	Victoria Holt, 27-Feb-86 * 002	Added the case RODATA for future use (to write const types *	into text space). * *	David L. Ballenger, 26-Feb-86 * 001	Changed ".align 1" to ".align 2" in efocde() to enable longword *	alignment of routines. * ******************************************************************/# include "mfile1"# include <sys/types.h># include <a.out.h># include <stab.h>int bswitch = 0; /* jpm: cld 153; set if never gen casel for switches */int proflg = 0;	/* are we generating profiling code? */int strftn = 0;  /* is the current function one which returns a value */int gdebug;int fdefflag;  /* are we within a function definition ? */char NULLNAME[8];int labelno;branch( n ){	/* output a branch to label n */	/* exception is an ordinary function branching to retlab: then, return */	if( n == retlab && !strftn ){		printf( "	ret\n" );		}	else printf( "	jbr 	L%d\n", n );	}int lastloc = { -1 };short log2tab[] = {0, 0, 1, 2, 2, 3, 3, 3, 3};#define LOG2SZ 9defalign(n) {	/* cause the alignment to become a multiple of n */	n /= SZCHAR;	if( lastloc != PROG && n > 1 ) printf( "	.align	%d\n", n >= 0 && n < LOG2SZ ? log2tab[n] : 0 );	}locctr( l ){	register temp;	/* l is PROG, RODATA (read-only data), ADATA, DATA, 	 * STRNG, ISTRNG, or STAB */	if( l == lastloc ) return(l);	temp = lastloc;	lastloc = l;	switch( l ){	case PROG:		printf( "	.text\n" );		psline();		break;	case DATA:	case ADATA:		printf( "	.data\n" );		break;	case STRNG:		printf( "	.data	1\n" );		break;	case ISTRNG:		printf( "	.data	2\n" );		break;	case STAB:		printf( "	.stab\n" );		break;	case RODATA:		printf("	.data\n" );		break;	default:		cerror( "illegal location counter" );		}	return( temp );	}deflab( n ){	/* output something to define the current position as label n */	printf( "L%d:\n", n );	}int crslab = 10;getlab(){	/* return a number usable for a label */	return( ++crslab );	}int ent_mask[] = {	0,0,0,0,0, 0xfc0, 0xf80, 0xf00, 0xe00, 0xc00, 0x800, 0};int reg_use = 11;efcode(){	/* code for the end of a function */	if( strftn ){  /* copy output (in R2) to caller */		register NODE *l, *r;		register struct symtab *p;		register TWORD t;		register int j;		int i;		p = &stab[curftn];		t = p->stype;		t = DECREF(t);		deflab( retlab );		i = getlab();	/* label for return area */#ifndef LCOMM		printf("	.data\n" );		printf("	.align	2\n" );		printf("L%d:	.space	%d\n", i, tsize(t, p->dimoff, p->sizoff)/SZCHAR );		printf("	.text\n" );#else		{ int sz = tsize(t, p->dimoff, p->sizoff) / SZCHAR;		if (sz % sizeof (int))			sz += sizeof (int) - (sz % sizeof (int));		printf("	.lcomm	L%d,%d\n", i, sz);		}#endif		psline();		printf("	movab	L%d,r1\n", i);		reached = 1;		l = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff );		l->tn.rval = 1;  /* R1 */		l->tn.lval = 0;  /* no offset */		r = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff );		r->tn.rval = 0;  /* R0 */		r->tn.lval = 0;		l = buildtree( UNARY MUL, l, NIL );		r = buildtree( UNARY MUL, r, NIL );		l = buildtree( ASSIGN, l, r );		l->in.op = FREE;		ecomp( l->in.left );		printf( "	movab	L%d,r0\n", i );		/* turn off strftn flag, so return sequence will be generated */		strftn = 0;		}	branch( retlab );#ifndef VMS	printf( "	.set	L%d,0x%x\n", ftnno, ent_mask[reg_use] );#else	printf( "	.set	L%d,%d	# Hex = 0x%x\n", ftnno, 0x3c| ent_mask[reg_use], ent_mask[reg_use]  );	/* KLS kludge, under VMS if you use regs 2-5, you must save them. */#endif	reg_use = 11;	p2bend();	fdefflag = 0;	}int ftlab1, ftlab2;bfcode( a, n ) int a[]; {	/* code for the beginning of a function; a is an array of		indices in stab for the arguments; n is the number */	register i;	register temp;	register struct symtab *p;	int off;	char *toreg();	locctr( PROG );	p = &stab[curftn];	printf( "	.align	2\n");	defnam( p );	temp = p->stype;	temp = DECREF(temp);	strftn = (temp==STRTY) || (temp==UNIONTY);	retlab = getlab();	/* routine prolog */	printf( "	.word	L%d\n", ftnno);	if (gdebug) {#ifdef STABDOT		pstabdot(N_SLINE, lineno);#else		pstab(NULLNAME, N_SLINE);		printf("0,%d,LL%d\n", lineno, labelno);		printf("LL%d:\n", labelno++);#endif	}	ftlab1 = getlab();	ftlab2 = getlab();	printf( "	jbr 	L%d\n", ftlab1);	printf( "L%d:\n", ftlab2);	if( proflg ) {	/* profile code */		i = getlab();		printf("	movab	L%d,r0\n", i);		printf("	jsb 	mcount\n");		printf("	.data\n");		printf("	.align	2\n");		printf("L%d:	.long	0\n", i);		printf("	.text\n");		psline();		}	off = ARGINIT;	for( i=0; i<n; ++i ){		p = &stab[a[i]];		if( p->sclass == REGISTER ){			temp = p->offset;  /* save register number */			p->sclass = PARAM;  /* forget that it is a register */			p->offset = NOOFFSET;			oalloc( p, &off );/*tbl*/		printf( "	%s	%d(ap),r%d\n", toreg(p->stype), p->offset/SZCHAR, temp );			p->offset = temp;  /* remember register number */			p->sclass = REGISTER;   /* remember that it is a register */			}		else if( p->stype == STRTY || p->stype == UNIONTY ) {			p->offset = NOOFFSET;			if( oalloc( p, &off ) ) cerror( "bad argument" );			SETOFF( off, ALSTACK );			}		else {			if( oalloc( p, &off ) ) cerror( "bad argument" );			}		}	fdefflag = 1;	}bccode(){ /* called just before the first executable statment */		/* by now, the automatics and register variables are allocated */	SETOFF( autooff, SZINT );	/* set aside store area offset */	p2bbeg( autooff, regvar );	reg_use = (reg_use > regvar ? regvar : reg_use);	}ejobcode( flag ){	/* called just before final exit */	/* flag is 1 if errors, 0 if none */	}aobeg(){	/* called before removing automatics from stab */	}aocode(p) struct symtab *p; {	/* called when automatic p removed from stab */	}aoend(){	/* called after removing all automatics from stab */	}defnam( p ) register struct symtab *p; {	/* define the current location as the name p->sname */	if( p->sclass == EXTDEF ){		printf( "	.globl	%s\n", exname( p->sname ) );		}	if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset );	else printf( "%s:\n", exname( p->sname ) );	}bycode( t, i ){#ifdef ASSTRINGSstatic	int	lastoctal = 0;#endif	/* put byte i+1 in a string */#ifdef ASSTRINGS	i &= 077;	if ( t < 0 ){		if ( i != 0 )	printf( "\"\n" );	} else {		if ( i == 0 ) printf("\t.ascii\t\"");		if ( t == '\\' || t == '"'){			lastoctal = 0;			printf("\\%c", t);		}			/*			 *	We escape the colon in strings so that			 *	c2 will, in its infinite wisdom, interpret			 *	the characters preceding the colon as a label.			 *	If we didn't escape the colon, c2 would			 *	throw away any trailing blanks or tabs after			 *	the colon, but reconstruct a assembly			 *	language semantically correct program.			 *	C2 hasn't been taught about strings.			 */		else if ( t == ':' || t < 040 || t >= 0177 ){			lastoctal++;			printf("\\%o",t);		}		else if ( lastoctal && '0' <= t && t <= '9' ){			lastoctal = 0;			printf("\"\n\t.ascii\t\"%c", t );		}		else		{				lastoctal = 0;			putchar(t);		}		if ( i == 077 ) printf("\"\n");	}#else	i &= 07;	if( t < 0 ){ /* end of the string */		if( i != 0 ) printf( "\n" );		}	else { /* stash byte t into string */		if( i == 0 ) printf( "	.byte	" );		else printf( "," );		printf( "0x%x", t );		if( i == 07 ) printf( "\n" );		}#endif	}zecode( n ){	/* n integer words of zeros */	OFFSZ temp;	if( n <= 0 ) return;	printf( "	.space	%d\n", (SZINT/SZCHAR)*n );	temp = n;	inoff += temp*SZINT;	}fldal( t ) unsigned t; { /* return the alignment of field of type t */	uerror( "illegal field type" );	return( ALINT );	}fldty( p ) struct symtab *p; { /* fix up type of field p */	;	}where(c){ /* print location of error  */	/* c is either 'u', 'c', or 'w' */	/* GCOS version */	fprintf( stderr, "%s, line %d: ", ftitle, lineno );	}/* tbl - toreg() returns a pointer to a char string		  which is the correct  "register move" for the passed type  */struct type_move {TWORD fromtype; char tostrng[8];} toreg_strs[] =	{	CHAR, "cvtbl",	SHORT, "cvtwl",	INT, "movl",	LONG, "movl",	FLOAT, "movf",	DOUBLE, "movd",	UCHAR,	"movzbl",	USHORT,	"movzwl",	UNSIGNED,	"movl",	ULONG,	"movl",	-1, ""	};char*toreg(type)	TWORD type;{	struct type_move *p;	for ( p=toreg_strs; p->fromtype > 0; p++)		if (p->fromtype == type) return(p->tostrng);	/* type not found, must be a pointer type */	return("movl");}/* tbl */main( argc, argv ) char *argv[]; {#ifdef BUFSTDERR	char errbuf[BUFSIZ];	setbuf(stderr, errbuf);#endif	return(mainp1( argc, argv ));	}struct sw heapsw[SWITSZ];	/* heap for switches */genswitch(p,n) register struct sw *p;{	/*	p points to an array of structures, each consisting		of a constant value and a label.		The first is >=0 if there is a default label;		its value is the label number		The entries p[1] to p[n] are the nontrivial cases		*/	register i;	register CONSZ j, range;	register dlab, swlab;	range = p[n].sval-p[1].sval;	if( (bswitch == 0) && range>0 && range <= 3*n && n>=4 )	{ 										/* implement a direct switch */		swlab = getlab();		dlab = p->slab >= 0 ? p->slab : getlab();		/* already in r0 */		printf("	casel	r0,$%ld,$%ld\n", p[1].sval, range);		printf("L%d:\n", swlab);		for( i=1,j=p[1].sval; i<=n; j++) {			printf("	.word	L%d-L%d\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),				swlab);			}		if( p->slab >= 0 ) branch( dlab );		else printf("L%d:\n", dlab);		return;		}	if( n>8 ) {	/* heap switch */		heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();		makeheap(p, n, 1);	/* build heap */		walkheap(1, n);	/* produce code */		if( p->slab >= 0 )			branch( dlab );		else			printf("L%d:\n", dlab);		return;	}	/* debugging code */	/* out for the moment	if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );	*/	/* simple switch code */	for( i=1; i<=n; ++i ){		/* already in r0 */		printf( "	cmpl	r0,$" );		printf( CONFMT, p[i].sval );		printf( "\n	jeql	L%d\n", p[i].slab );		}	if( p->slab>=0 ) branch( p->slab );	}makeheap(p, m, n)register struct sw *p;{	register int q;	q = select(m);	heapsw[n] = p[q];	if( q>1 ) makeheap(p, q-1, 2*n);	if( q<m ) makeheap(p+q, m-q, 2*n+1);}select(m) {	register int l,i,k;	for(i=1; ; i*=2)		if( (i-1) > m ) break;	l = ((k = i/2 - 1) + 1)/2;	return( l + (m-k < l ? m-k : l));}walkheap(start, limit){	int label;	if( start > limit ) return;	printf("	cmpl	r0,$%d\n",  heapsw[start].sval);	printf("	jeql	L%d\n", heapsw[start].slab);	if( (2*start) > limit ) {		printf("	jbr 	L%d\n", heapsw[0].slab);		return;	}	if( (2*start+1) <= limit ) {		label = getlab();		printf("	jgtr	L%d\n", label);	} else		printf("	jgtr	L%d\n", heapsw[0].slab);	walkheap( 2*start, limit);	if( (2*start+1) <= limit ) {		printf("L%d:\n", label);		walkheap( 2*start+1, limit);	}}

⌨️ 快捷键说明

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