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

📄 local2.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
# include "mfile2"/* a lot of the machine dependent parts of the second pass */# define BITMASK(n) ((1L<<n)-1)lineid( l, fn ) char *fn; {	/* identify line l and file fn */	printf( "/	line %d, file %s\n", l, fn );	}eobl2(){	OFFSZ spoff;	/* offset from stack pointer */	spoff = maxoff;	if( spoff >= AUTOINIT ) spoff -= AUTOINIT;	spoff /= SZCHAR;	SETOFF(spoff,2);	printf( "	.F%d = %Ld.\n", ftnno, spoff );	if( fltused ) {		fltused = 0;		printf( "	.globl	fltused\n" );		}	}struct hoptab { int opmask; char * opstring; } ioptab[]= {	ASG PLUS, "add",	ASG MINUS, "sub",	ASG OR,	"bis",	ASG AND,	"bic",	ASG ER,	"xor",	ASG MUL, "mul",	ASG DIV, "div",	ASG MOD, "div",	ASG LS,	"asl",	ASG RS,	"asr",	-1, ""    };hopcode( f, o ){	/* output the appropriate string from the above table */	register struct hoptab *q;	for( q = ioptab;  q->opmask>=0; ++q ){		if( q->opmask == o ){			printf( "%s", q->opstring );			if( f == 'F' ) printf( "f" );			return;			}		}	cerror( "no hoptab for %s", opst[o] );	}char *rnames[]= {  /* keyed to register number tokens */	"r0", "r1",	"r2", "r3", "r4",	"r5", "sp", "pc",	"fr0", "fr1", "fr2", "fr3",	"fr4", "fr5",	/* not accumulators - used for temps */	};int rstatus[] = {	SAREG|STAREG, SAREG|STAREG,	SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,	/* use as scratch if not reg var */	SAREG, SAREG, SAREG,	SBREG|STBREG, SBREG|STBREG, SBREG|STBREG, SBREG|STBREG,	SBREG, SBREG,	};NODE *brnode;int brcase;int toff = 0; /* number of stack locations used for args */zzzcode( p, c ) NODE *p; {	register m;	switch( c ){	case 'B':	/* output b if type is byte */		if( p->type == CHAR || p->type == UCHAR ) printf( "b" );		return;	case 'N':  /* logical ops, turned into 0-1 */		/* use register given by register 1 */		cbgen( 0, m=getlab(), 'I' );		deflab( p->label );		printf( "	clr	%s\n", rnames[getlr( p, '1' )->rval] );		if( p->type == LONG || p->type == ULONG )			printf( "	clr	%s\n", rnames[getlr( p, '1' )->rval + 1] );		deflab( m );		return;	case 'I':	case 'F':		cbgen( p->op, p->label, c );		return;	case 'A':	case 'C':		/* logical operators for longs		   defer comparisons until branch occurs */		brnode = tcopy( p );		brcase = c;		return;	case 'H':  /* fix up unsigned shifts */		{	register NODE *q;			register r, l;			TWORD t;			if( p->op == ASG LS ) return;			if( p->op != ASG RS ) cerror( "ZH bad" );			if( p->left->op != REG ) cerror( "SH left bad" );			r = p->left->rval;			t = p->left->type;			l = (t==LONG || t == ULONG );			if( t != UNSIGNED && t != UCHAR && t != ULONG ) return;  /* signed is ok */			/* there are three cases:  right side is a constant,				and has the shift value; right side is				a temporary reg, and has the - shift value,				and right side is something else: A1 has the				- shift value then */			/* in the case where the value is known (rhs a constant),				the mask is just computed and put out... */			if( p->right->op == ICON ){				int s;				s = p->right->lval;				if( l ){					if( s >= 16 ){						printf( "	clr	r%d\n", r );						s -= 16;						++r;						}					}				if( s >= 16 ) printf( "	clr	r%d\n", r );				else {					m = 0100000;					m >>= s;  /* sign extends... */					m <<= 1;					printf( "	bic	$%o,r%d\n", m, r );					}				return;				}			/* general case */			if( istnode( p->right ) ) q = p->right;			else q = getlr( p, '1' );  /* where -shift is stored */			/* first, we store the shifted value on the stack */			printf( "	mov	r%d,-(sp)\n", r );			if( l ) printf( "	mov	r%d,-(sp)\n", r+1 );			/* now, make a mask */			printf( "	mov	$100000,r%d\n", r );			if( l ) printf( "	clr	r%d\n", r+1 );						/* shift (arithmetically ) */			if( l ) expand( q, RNOP, "	ashc	AR" );			else expand( q, RNOP, "	ash	AR" );			printf( ",r%d\n", r );			if( l ) printf( "	ashc	$1,r%d\n", r );			else printf( "	asl	r%d\n", r );			/* now, we have a mask: use it to clear sp, and reload */			if( l ){				printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r+1, r+1 );				}			printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r, r );			/* whew! */			return;			}	case 'V':		/* sign extend or not -- register is one less than the		   left descendent */		m = p->left->rval - 1;		if( ISUNSIGNED(p->type) ){			printf( "	clr	r%d\n", m );			}		else {			printf( "	sxt	r%d\n", m );			}		return;		/* stack management macros */	case '-':		if( toff ++ ) printf( "-" );		printf( "(sp)" );		return;	case '4':		if( toff == 0 ) ++toff;  /* can't push doubles that way */		printf( "-(sp)" );		toff += 4;		return;	case '~':		/* complimented CR */		p->right->lval = ~p->right->lval;		conput( getlr( p, 'R' ) );		p->right->lval = ~p->right->lval;		return;	case 'M':		/* negated CR */		p->right->lval = -p->right->lval;		conput( getlr( p, 'R' ) );		p->right->lval = -p->right->lval;		return;	case 'L':  /* INIT for long constants */		{			unsigned hi, lo;			lo = p->left->lval & BITMASK(SZINT);			hi = ( p->left->lval >> SZINT ) & BITMASK(SZINT);			printf( "	%o; %o\n", hi, lo );			return;		}	case 'T':		/* Truncate longs for type conversions:		    LONG|ULONG -> CHAR|UCHAR|INT|UNSIGNED		   increment offset to second word */		m = p->type;		p = p->left;		switch( p->op ){		case NAME:		case OREG:			p->lval += SZINT/SZCHAR;			return;		case REG:			rfree( p->rval, p->type );			p->rval += 1;			p->type = m;			rbusy( p->rval, p->type );			return;		default:			cerror( "Illegal ZT type conversion" );			return;			}	case 'U':		/* same as AL for exp under U* */		if( p->left->op == UNARY MUL ) {			adrput( getlr( p->left, 'L' ) );			return;			}		cerror( "Illegal ZU" );		/* NO RETURN */	case 'W':	/* structure size */		if( p->op == STASG )			printf( "%d", p->stsize);		else	cerror( "Not a structure" );		return;	case 'S':  /* structure assignment */		{			register NODE *l, *r;			register size, count;			if( p->op == STASG ){				l = p->left;				r = p->right;				}			else if( p->op == STARG ){  /* store an arg onto the stack */				r = p->left;				}			else cerror( "STASG bad" );			if( r->op == ICON ) r->op = NAME;			else if( r->op == REG ) r->op = OREG;			else if( r->op != OREG ) cerror( "STASG-r" );			size = p->stsize;			count = size / 2;			r->lval += size;			if( p->op == STASG ) l->lval += size;			while( count-- ){ /* simple load/store loop */				r->lval -= 2;				expand( r, FOREFF, "	mov	AR," );				if( p->op == STASG ){					l->lval -= 2;					expand( l, FOREFF, "AR\n" );					}				else {					printf( "-(sp)\n" );					}				}			if( r->op == NAME ) r->op = ICON;			else if( r->op == OREG ) r->op = REG;			}		break;	default:		cerror( "illegal zzzcode" );		}	}rmove( rt, rs, t ) TWORD t; {	printf( "	%s	%s,%s\n", (t==FLOAT||t==DOUBLE)?"movf":"mov", rnames[rs], rnames[rt] );	}struct resprefrespref[] = {	INTAREG|INTBREG,	INTAREG|INTBREG,	INAREG|INBREG,	INAREG|INBREG|SOREG|STARREG|SNAME|STARNM|SCON,	INTEMP,	INTEMP,	FORARG,	FORARG,	INTAREG,	SOREG|SNAME,	0,	0 };setregs(){ /* set up temporary registers */	register i;	/* use any unused variable registers as scratch registers */	fregs = maxtreg>=MINRVAR ? maxtreg + 1 : MINRVAR;	if( xdebug ){		/* -x changes number of free regs to 2, -xx to 3, etc. */		if( (xdebug+1) < fregs ) fregs = xdebug+1;		}	/* NOTE: for pdp11 fregs <= 4 for float regs */	if( fregs > 4 ) fregs = 4;	for( i=MINRVAR; i<=MAXRVAR; i++ )		rstatus[i] = i<fregs ? SAREG|STAREG : SAREG;	}szty(t) TWORD t; { /* size, in words, needed to hold thing of type t */	/* really is the number of registers to hold type t */	switch( t ) {	case LONG:	case ULONG:		return( SZLONG/SZINT );	default:		return(1);		}	}rewfld( p ) NODE *p; {	return(1);	}callreg(p) NODE *p; {	return( (p->type==DOUBLE||p->type==FLOAT) ? FR0 : R0 );	}shltype( o, p ) NODE *p; {	if( o == NAME|| o==REG || o == ICON || o == OREG ) return( 1 );	return( o==UNARY MUL && shumul(p->left) );	}flshape( p ) register NODE *p; {	register o = p->op;	if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 );	return( o==UNARY MUL && shumul(p->left)==STARNM );	}shtemp( p ) register NODE *p; {	if( p->op == UNARY MUL ) p = p->left;	if( p->op == REG || p->op == OREG ) return( !istreg( p->rval ) );	return( p->op == NAME || p->op == ICON );	}spsz( t, v ) TWORD t; CONSZ v; {	/* is v the size to increment something of type t */	if( !ISPTR(t) ) return( 0 );	t = DECREF(t);	if( ISPTR(t) ) return( v == 2 );	switch( t ){	case UCHAR:	case CHAR:		return( v == 1 );	case INT:	case UNSIGNED:		return( v == 2 );	case FLOAT:		return( v == 4 );	case DOUBLE:		return( v == 8 );		}	return( 0 );	}shumul( p ) register NODE *p; {	register o;	o = p->op;	if( o == NAME || o == OREG || o == ICON ) return( STARNM );	if( ( o == INCR || o == ASG MINUS ) &&	    ( p->left->op == REG && p->right->op == ICON ) &&	    p->right->name[0] == '\0' &&	    spsz( p->left->type, p->right->lval ) )		return( STARREG );	return( 0 );	}adrcon( val ) CONSZ val; {	printf( CONFMT, val );	}conput( p ) register NODE *p; {	switch( p->op ){	case ICON:		acon( p );		return;	case REG:		printf( "%s", rnames[p->rval] );		return;	default:		cerror( "illegal conput" );		}	}insput( p ) NODE *p; {	cerror( "insput" );	}upput( p ) NODE *p; {	/* output the address of the second word in the

⌨️ 快捷键说明

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