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

📄 c12.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
#/* *		C compiler part 2 -- expression optimizer * */#include "c1.h"optim(atree)struct tnode *atree;{	struct { int intx[4]; };	register op, dope;	int d1, d2;	struct tnode *t;	register struct tnode *tree;	if ((tree=atree)==0)		return(0);	if ((op = tree->op)==0)		return(tree);	if (op==NAME && tree->class==AUTO) {		tree->class = OFFS;		tree->regno = 5;		tree->offset = tree->nloc;	}	dope = opdope[op];	if ((dope&LEAF) != 0) {		if (op==FCON		 && tree->fvalue.intx[1]==0		 && tree->fvalue.intx[2]==0		 && tree->fvalue.intx[3]==0) {			tree->op = SFCON;			tree->value = tree->fvalue.intx[0];		}		return(tree);	}	if ((dope&BINARY) == 0)		return(unoptim(tree));	/* is known to be binary */	if (tree->type==CHAR)		tree->type = INT;	switch(op) {	/*	 * PDP-11 special:	 * generate new =&~ operator out of =&	 * by complementing the RHS.	 */	case ASAND:		tree->op = ASANDN;		tree->tr2 = tnode(COMPL, tree->tr2->type, tree->tr2);		break;	/*	 * On the PDP-11, int->ptr via multiplication	 * Longs are just truncated.	 */	case LTOP:		tree->op = ITOP;		tree->tr1 = unoptim(tnode(LTOI,INT,tree->tr1));	case ITOP:		tree->op = TIMES;		break;	case MINUS:		if ((t = isconstant(tree->tr2)) && (t->type!=UNSIGN || tree->type!=LONG)) {			tree->op = PLUS;			if (t->type==DOUBLE)				/* PDP-11 FP representation */				t->value =^ 0100000;			else				t->value = -t->value;		}		break;	}	op = tree->op;	dope = opdope[op];	if (dope&LVALUE && tree->tr1->op==FSEL)		return(lvfield(tree));	if ((dope&COMMUTE)!=0) {		d1 = tree->type;		tree = acommute(tree);		if (tree->op == op)			tree->type = d1;		/*		 * PDP-11 special:		 * replace a&b by a ANDN ~ b.		 * This will be undone when in		 * truth-value context.		 */		if (tree->op!=AND)			return(tree);		/*		 * long & pos-int is simpler		 */		if (tree->type==LONG && tree->tr2->op==ITOL		 && (tree->tr2->tr1->op==CON && tree->tr2->tr1->value>=0		   || tree->tr2->tr1->type==UNSIGN)) {			tree->type = UNSIGN;			t = tree->tr2;			tree->tr2 = tree->tr2->tr1;			t->tr1 = tree;			tree->tr1 = tnode(LTOI, UNSIGN, tree->tr1);			return(optim(t));		}		/*		 * Keep constants to the right		 */		if ((tree->tr1->op==ITOL && tree->tr1->tr1->op==CON)		  || tree->tr1->op==LCON) {			t = tree->tr1;			tree->tr1 = tree->tr2;			tree->tr2 = t;		}		tree->op = ANDN;		op = ANDN;		tree->tr2 = tnode(COMPL, tree->tr2->type, tree->tr2);	}    again:	tree->tr1 = optim(tree->tr1);	tree->tr2 = optim(tree->tr2);	if (tree->type == LONG) {		t = lconst(tree->op, tree->tr1, tree->tr2);		if (t)			return(t);	}	if ((dope&RELAT) != 0) {		if ((d1=degree(tree->tr1)) < (d2=degree(tree->tr2))		 || d1==d2 && tree->tr1->op==NAME && tree->tr2->op!=NAME) {			t = tree->tr1;			tree->tr1 = tree->tr2;			tree->tr2 = t;			tree->op = maprel[op-EQUAL];		}		if (tree->tr1->type==CHAR && tree->tr2->op==CON		 && (dcalc(tree->tr1, 0) <= 12 || tree->tr1->op==STAR)		 && tree->tr2->value <= 127 && tree->tr2->value >= 0)			tree->tr2->type = CHAR;	}	d1 = max(degree(tree->tr1), islong(tree->type));	d2 = max(degree(tree->tr2), 0);	switch (op) {	/*	 * In assignment to fields, treat all-zero and all-1 specially.	 */	case FSELA:		if (tree->tr2->op==CON && tree->tr2->value==0) {			tree->op = ASAND;			tree->tr2->value = ~tree->mask;			return(optim(tree));		}		if (tree->tr2->op==CON && tree->mask==tree->tr2->value) {			tree->op = ASOR;			return(optim(tree));		}	case LTIMES:	case LDIV:	case LMOD:	case LASTIMES:	case LASDIV:	case LASMOD:		tree->degree = 10;		break;	case ANDN:		if (isconstant(tree->tr2) && tree->tr2->value==0) {			return(tree->tr1);		}		goto def;	case CALL:		tree->degree = 10;		break;	case QUEST:	case COLON:		tree->degree = max(d1, d2);		break;	case DIVIDE:	case ASDIV:	case ASTIMES:	case PTOI:		if (tree->tr2->op==CON && tree->tr2->value==1)			return(tree->tr1);	case MOD:	case ASMOD:		if (tree->tr1->type==UNSIGN && ispow2(tree))			return(pow2(tree));		if ((op==MOD||op==ASMOD) && tree->type==DOUBLE) {			error("Floating %% not defined");			tree->type = INT;		}	case ULSH:	case ASULSH:		d1 =+ 2;		d2 =+ 2;		if (tree->type==LONG)			return(hardlongs(tree));		goto constant;	case LSHIFT:	case RSHIFT:	case ASRSH:	case ASLSH:		if (tree->tr2->op==CON && tree->tr2->value==0) {			return(tree->tr1);		}		/*		 * PDP-11 special: turn right shifts into negative		 * left shifts		 */		if (tree->type == LONG) {			d1++;			d2++;		}		if (op==LSHIFT||op==ASLSH)			goto constant;		if (tree->tr2->op==CON && tree->tr2->value==1		 && tree->tr1->type!=UNSIGN)			goto constant;		op =+ (LSHIFT-RSHIFT);		tree->op = op;		tree->tr2 = tnode(NEG, tree->type, tree->tr2);		if (tree->tr1->type==UNSIGN) {			if (tree->op==LSHIFT)				tree->op = ULSH;			else if (tree->op==ASLSH)				tree->op = ASULSH;		}		goto again;	constant:		if (tree->tr1->op==CON && tree->tr2->op==CON) {			const(op, &tree->tr1->value, tree->tr2->value);			return(tree->tr1);		}	def:	default:		if (dope&RELAT) {			if (tree->tr1->type==LONG)	/* long relations are a mess */				d1 = 10;			if (opdope[tree->tr1->op]&RELAT && tree->tr2->op==CON			 && tree->tr2->value==0) {				tree = tree->tr1;				switch(op) {				case GREATEQ:					return(&cone);				case LESS:					return(&czero);				case LESSEQ:				case EQUAL:					tree->op = notrel[tree->op-EQUAL];				}				return(tree);			}		}		tree->degree = d1==d2? d1+islong(tree->type): max(d1, d2);		break;	}	return(tree);}unoptim(atree)struct tnode *atree;{	struct { int intx[4]; };	register struct tnode *subtre, *tree;	register int *p;	double static fv;	struct ftconst *fp;	if ((tree=atree)==0)		return(0);    again:	if (tree->op==AMPER && tree->tr1->op==STAR) {		subtre = tree->tr1->tr1;		subtre->type = tree->type;		return(optim(subtre));	}	subtre = tree->tr1 = optim(tree->tr1);	switch (tree->op) {	case ITOL:		if (subtre->op==CON && subtre->type==INT && subtre->value<0) {			subtre = getblk(sizeof(struct lconst));			subtre->op = LCON;			subtre->type = LONG;			subtre->lvalue = tree->tr1->value;			return(subtre);		}		break;	case FTOI:		if (tree->type==UNSIGN) {			tree->op = FTOL;			tree->type = LONG;			tree = tnode(LTOI, UNSIGN, tree);		}		break;	case LTOF:		if (subtre->op==LCON) {			tree = getblk(sizeof(*fp));			tree->op = FCON;			tree->type = DOUBLE;			tree->value = isn++;			tree->fvalue = subtre->lvalue;			return(optim(tree));		}		break;	case ITOF:		if (tree->tr1->type==UNSIGN) {			tree->tr1 = tnode(ITOL, LONG, tree->tr1);			tree->op = LTOF;			tree = optim(tree);		}		if (subtre->op!=CON)			break;		fv = subtre->value;		p = &fv;		p++;		if (*p++==0 && *p++==0 && *p++==0) {			tree = getblk(sizeof(*fp));			tree->op = SFCON;			tree->type = DOUBLE;			tree->value = * (int *) &fv;			tree->fvalue = fv;			return(tree);		}		break;	case ITOC:		p = tree->tr1;		/*		 * Sign-extend PDP-11 characters		 */		if (p->op==CON) {			p->value = p->value << 8 >> 8;			return(p);		} else if (p->op==NAME) {			p->type = CHAR;			return(p);		}		break;	case LTOI:		p = tree->tr1;		switch (p->op) {		case LCON:			p->op = CON;			p->type = tree->type;			p->value = p->lvalue;			return(p);		case NAME:			p->offset =+ 2;			p->type = tree->type;			return(p);		case STAR:			p->type = tree->type;			p->tr1->type = tree->type+PTR;			p->tr1 = tnode(PLUS, tree->type, p->tr1, tconst(2, INT));			return(optim(p));		case ITOL:			return(p->tr1);		case PLUS:		case MINUS:		case AND:		case ANDN:		case OR:		case EXOR:			p->tr2 = tnode(LTOI, tree->type, p->tr2);		case NEG:		case COMPL:			p->tr1 = tnode(LTOI, tree->type, p->tr1);			p->type = tree->type;			return(optim(p));		}		break;	case FSEL:		tree->op = AND;		tree->tr1 = tree->tr2->tr1;		tree->tr2->tr1 = subtre;		tree->tr2->op = RSHIFT;		tree->tr1->value = (1 << tree->tr1->value) - 1;		return(optim(tree));	case FSELR:		tree->op = LSHIFT;		tree->type = UNSIGN;		tree->tr1 = tree->tr2;		tree->tr1->op = AND;		tree->tr2 = tree->tr2->tr2;		tree->tr1->tr2 = subtre;		tree->tr1->tr1->value = (1 << tree->tr1->tr1->value) -1;		return(optim(tree));	case AMPER:		if (subtre->op==STAR)			return(subtre->tr1);		if (subtre->op==NAME && subtre->class == OFFS) {			p = tnode(PLUS, tree->type, subtre, tree);			subtre->type = tree->type;			tree->op = CON;			tree->type = INT;			tree->degree = 0;			tree->value = subtre->offset;			subtre->class = REG;			subtre->nloc = subtre->regno;			subtre->offset = 0;			return(optim(p));		}		break;	case STAR:		if (subtre->op==AMPER) {			subtre->tr1->type = tree->type;			return(subtre->tr1);		}		if (tree->type==STRUCT)			break;		if (subtre->op==NAME && subtre->class==REG) {			subtre->type = tree->type;			subtre->class = OFFS;			subtre->regno = subtre->nloc;			return(subtre);		}		p = subtre->tr1;		if ((subtre->op==INCAFT||subtre->op==DECBEF)&&tree->type!=LONG		 && p->op==NAME && p->class==REG && p->type==subtre->type) {			p->type = tree->type;			p->op = subtre->op==INCAFT? AUTOI: AUTOD;			return(p);		}		if (subtre->op==PLUS && p->op==NAME && p->class==REG) {			if (subtre->tr2->op==CON) {				p->offset =+ subtre->tr2->value;				p->class = OFFS;				p->type = tree->type;				p->regno = p->nloc;				return(p);			}			if (subtre->tr2->op==AMPER) {				subtre = subtre->tr2->tr1;				subtre->class =+ XOFFS-EXTERN;				subtre->regno = p->nloc;				subtre->type = tree->type;				return(subtre);			}		}		break;	case EXCLA:		if ((opdope[subtre->op]&RELAT)==0)			break;		tree = subtre;		tree->op = notrel[tree->op-EQUAL];		break;	case COMPL:		if (tree->type==CHAR)			tree->type = INT;		if (tree->op == subtre->op)			return(subtre->tr1);		if (subtre->op==CON) {			subtre->value = ~subtre->value;			return(subtre);		}		if (subtre->op==LCON) {			subtre->lvalue = ~subtre->lvalue;			return(subtre);		}		if (subtre->op==ITOL) {			if (subtre->tr1->op==CON) {				tree = getblk(sizeof(struct lconst));				tree->op = LCON;				tree->type = LONG;				if (subtre->tr1->type==UNSIGN)					tree->lvalue = ~(long)(unsigned)subtre->tr1->value;				else					tree->lvalue = ~subtre->tr1->value;				return(tree);			}			if (subtre->tr1->type==UNSIGN)				break;			subtre->op = tree->op;			subtre->type = subtre->tr1->type;			tree->op = ITOL;			tree->type = LONG;			goto again;		}	case NEG:		if (tree->type==CHAR)			tree->type = INT;		if (tree->op==subtre->op)			return(subtre->tr1);		if (subtre->op==CON) {			subtre->value = -subtre->value;			return(subtre);		}		if (subtre->op==LCON) {			subtre->lvalue = -subtre->lvalue;			return(subtre);		}		if (subtre->op==ITOL && subtre->tr1->op==CON) {			tree = getblk(sizeof(struct lconst));			tree->op = LCON;			tree->type = LONG;			if (subtre->tr1->type==UNSIGN)				tree->lvalue = -(long)(unsigned)subtre->tr1->value;			else				tree->lvalue = -subtre->tr1->value;			return(tree);		}		/*		 * PDP-11 FP negation		 */		if (subtre->op==SFCON) {			subtre->value =^ 0100000;			subtre->fvalue.intx[0] =^ 0100000;			return(subtre);		}		if (subtre->op==FCON) {			subtre->fvalue.intx[0] =^ 0100000;			return(subtre);		}	}	if ((opdope[tree->op]&LEAF)==0)		tree->degree = max(islong(tree->type), degree(subtre));	return(tree);

⌨️ 快捷键说明

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