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

📄 c12.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* * Deal with assignments to partial-word fields. * The game is that select(x) =+ y turns into * select(x =+ select(y)) where the shifts and masks * are chosen properly.  The outer select * is discarded where the value doesn't matter. * Sadly, overflow is undetected on =+ and the like. * Pure assignment is handled specially. */lvfield(at)struct tnode *at;{	register struct tnode *t, *t1;	register struct fasgn *t2;	t = at;	switch (t->op) {	case ASSIGN:		t2 = getblk(sizeof(*t2));		t2->op = FSELA;		t2->type = UNSIGN;		t1 = t->tr1->tr2;		t2->mask = ((1<<t1->tr1->value)-1)<<t1->tr2->value;		t2->tr1 = t->tr1;		t2->tr2 = t->tr2;		t = t2;	case ASANDN:	case ASPLUS:	case ASMINUS:	case ASOR:	case ASXOR:	case INCBEF:	case INCAFT:	case DECBEF:	case DECAFT:		t1 = t->tr1;		t1->op = FSELR;		t->tr1 = t1->tr1;		t1->tr1 = t->tr2;		t->tr2 = t1;		t1 = t1->tr2;		t1 = tnode(COMMA, INT, tconst(t1->tr1->value, INT),			tconst(t1->tr2->value, INT));		return(optim(tnode(FSELT, UNSIGN, t, t1)));	}	error("Unimplemented field operator");	return(t);}#define	LSTSIZ	20struct acl {	int nextl;	int nextn;	struct tnode *nlist[LSTSIZ];	struct tnode *llist[LSTSIZ+1];};acommute(atree){	struct acl acl;	int d, i, op, flt, d1;	register struct tnode *t1, **t2, *tree;	struct tnode *t;	acl.nextl = 0;	acl.nextn = 0;	tree = atree;	op = tree->op;	flt = isfloat(tree);	insert(op, tree, &acl);	acl.nextl--;	t2 = &acl.llist[acl.nextl];	if (!flt) {		/* put constants together */		for (i=acl.nextl; i>0; i--) {			if (t2[0]->op==CON && t2[-1]->op==CON) {				acl.nextl--;				t2--;				const(op, &t2[0]->value, t2[1]->value);			} else if (t = lconst(op, t2[-1], t2[0])) {				acl.nextl--;				t2--;				t2[0] = t;			}		}	}	if (op==PLUS || op==OR) {		/* toss out "+0" */		if (acl.nextl>0 && (t1 = isconstant(*t2)) && t1->value==0		 || (*t2)->op==LCON && (*t2)->lvalue==0) {			acl.nextl--;			t2--;		}		if (acl.nextl <= 0) {			if ((*t2)->type==CHAR)				*t2 = tnode(LOAD, tree->type, *t2, NULL);			(*t2)->type = tree->type;			return(*t2);		}		/* subsume constant in "&x+c" */		if (op==PLUS && t2[0]->op==CON && t2[-1]->op==AMPER) {			t2--;			t2[0]->tr1->offset =+ t2[1]->value;			acl.nextl--;		}	} else if (op==TIMES || op==AND) {		t1 = acl.llist[acl.nextl];		if (t1->op==CON) {			if (t1->value==0)				return(t1);			if (op==TIMES && t1->value==1 && acl.nextl>0)				if (--acl.nextl <= 0) {					t1 = acl.llist[0];					if (tree->type == UNSIGN)						t1->type = tree->type;					return(t1);				}		}	}	if (op==PLUS && !flt)		distrib(&acl);	tree = *(t2 = &acl.llist[0]);	d = max(degree(tree), islong(tree->type));	if (op==TIMES && !flt)		d++;	for (i=0; i<acl.nextl; i++) {		t1 = acl.nlist[i];		t1->tr2 = t = *++t2;		d1 = degree(t);		/*		 * PDP-11 strangeness:		 * rt. op of ^ must be in a register.		 */		if (op==EXOR && dcalc(t, 0)<=12) {			t1->tr2 = t = optim(tnode(LOAD, t->type, t));			d1 = t->degree;		}		t1->degree = d = d==d1? d+islong(t1->type): max(d, d1);		t1->tr1 = tree;		tree = t1;		if (tree->type==LONG) {			if (tree->op==TIMES)				tree = hardlongs(tree);			else if (tree->op==PLUS && (t = isconstant(tree->tr1))			       && t->value < 0 && t->type!=UNSIGN) {				tree->op = MINUS;				t->value = - t->value;				t = tree->tr1;				tree->tr1 = tree->tr2;				tree->tr2 = t;			}		}	}	if (tree->op==TIMES && ispow2(tree))		tree->degree = max(degree(tree->tr1), islong(tree->type));	return(tree);}distrib(list)struct acl *list;{/* * Find a list member of the form c1c2*x such * that c1c2 divides no other such constant, is divided by * at least one other (say in the form c1*y), and which has * fewest divisors. Reduce this pair to c1*(y+c2*x) * and iterate until no reductions occur. */	register struct tnode **p1, **p2;	struct tnode *t;	int ndmaj, ndmin;	struct tnode **dividend, **divisor;	struct tnode **maxnod, **mindiv;    loop:	maxnod = &list->llist[list->nextl];	ndmaj = 1000;	dividend = 0;	for (p1 = list->llist; p1 <= maxnod; p1++) {		if ((*p1)->op!=TIMES || (*p1)->tr2->op!=CON)			continue;		ndmin = 0;		for (p2 = list->llist; p2 <= maxnod; p2++) {			if (p1==p2 || (*p2)->op!=TIMES || (*p2)->tr2->op!=CON)				continue;			if ((*p1)->tr2->value == (*p2)->tr2->value) {				(*p2)->tr2 = (*p1)->tr1;				(*p2)->op = PLUS;				(*p1)->tr1 = (*p2);				*p1 = optim(*p1);				squash(p2, maxnod);				list->nextl--;				goto loop;			}			if (((*p2)->tr2->value % (*p1)->tr2->value) == 0)				goto contmaj;			if (((*p1)->tr2->value % (*p2)->tr2->value) == 0) {				ndmin++;				mindiv = p2;			}		}		if (ndmin > 0 && ndmin < ndmaj) {			ndmaj = ndmin;			dividend = p1;			divisor = mindiv;		}    contmaj:;	}	if (dividend==0)		return;	t = list->nlist[--list->nextn];	p1 = dividend;	p2 = divisor;	t->op = PLUS;	t->type = (*p1)->type;	t->tr1 = (*p1);	t->tr2 = (*p2)->tr1;	(*p1)->tr2->value =/ (*p2)->tr2->value;	(*p2)->tr1 = t;	t = optim(*p2);	if (p1 < p2) {		*p1 = t;		squash(p2, maxnod);	} else {		*p2 = t;		squash(p1, maxnod);	}	list->nextl--;	goto loop;}squash(p, maxp)struct tnode **p, **maxp;{	register struct tnode **np;	for (np = p; np < maxp; np++)		*np = *(np+1);}const(op, vp, av)int *vp;{	register int v;	struct { unsigned u;};	v = av;	switch (op) {	case PTOI:		(*vp).u =/ v;		return;	case PLUS:		*vp =+ v;		return;	case TIMES:		*vp =* v;		return;	case AND:		*vp =& v;		return;	case OR:		*vp =| v;		return;	case EXOR:		*vp =^ v;		return;	case DIVIDE:	case MOD:		if (v==0)			error("Divide check");		else			if (op==DIVIDE)				*vp =/ v;			else				*vp =% v;		return;	case RSHIFT:		*vp =>> v;		return;	case LSHIFT:		*vp =<< v;		return;	case ANDN:		*vp =& ~ v;		return;	}	error("C error: const");}struct tnode *lconst(op, lp, rp)register struct tnode *lp, *rp;{	long l, r;	if (lp->op==LCON)		l = lp->lvalue;	else if (lp->op==ITOL && lp->tr1->op==CON) {		if (lp->tr1->type==INT)			l = lp->tr1->value;		else			l = (unsigned)lp->tr1->value;	} else		return(0);	if (rp->op==LCON)		r = rp->lvalue;	else if (rp->op==ITOL && rp->tr1->op==CON) {		if (rp->tr1->type==INT)			r = rp->tr1->value;		else			r = (unsigned)rp->tr1->value;	} else		return(0);	switch (op) {	case PLUS:		l += r;		break;	case MINUS:		l -= r;		break;	case TIMES:	case LTIMES:		l *= r;		break;	case DIVIDE:	case LDIV:		if (r==0)			error("Divide check");		else			l /= r;		break;	case MOD:	case LMOD:		if (r==0)			error("Divide check");		else			l %= r;		break;	case AND:		l &= r;		break;	case ANDN:		l &= ~r;		break;	case OR:		l |= r;		break;	case EXOR:		l ^= r;		break;	case LSHIFT:		l <<= r;		break;	case RSHIFT:		l >>= r;		break;	default:		return(0);	}	if (lp->op==LCON) {		lp->lvalue = l;		return(lp);	}	lp = getblk(sizeof(struct lconst));	lp->op = LCON;	lp->type = LONG;	lp->lvalue = l;	return(lp);}insert(op, atree, alist)struct acl *alist;{	register d;	register struct acl *list;	register struct tnode *tree;	int d1, i;	struct tnode *t;	tree = atree;	list = alist;ins:	if (tree->op != op)		tree = optim(tree);	if (tree->op == op && list->nextn < LSTSIZ-2) {		list->nlist[list->nextn++] = tree;		insert(op, tree->tr1, list);		insert(op, tree->tr2, list);		return;	}	if (!isfloat(tree)) {		/* c1*(x+c2) -> c1*x+c1*c2 */		if ((tree->op==TIMES||tree->op==LSHIFT)		  && tree->tr2->op==CON && tree->tr2->value>0		  && tree->tr1->op==PLUS && tree->tr1->tr2->op==CON) {			d = tree->tr2->value;			if (tree->op==TIMES)				tree->tr2->value =* tree->tr1->tr2->value;			else				tree->tr2->value = tree->tr1->tr2->value << d;			tree->tr1->tr2->value = d;			tree->tr1->op = tree->op;			tree->op = PLUS;			tree = optim(tree);			if (op==PLUS)				goto ins;		}	}	d = degree(tree);	for (i=0; i<list->nextl; i++) {		if ((d1=degree(list->llist[i]))<d) {			t = list->llist[i];			list->llist[i] = tree;			tree = t;			d = d1;		}	}	list->llist[list->nextl++] = tree;}tnode(op, type, tr1, tr2)struct tnode *tr1, *tr2;{	register struct tnode *p;	p = getblk(sizeof(*p));	p->op = op;	p->type = type;	p->degree = 0;	p->tr1 = tr1;	if (opdope[op]&BINARY)		p->tr2 = tr2;	else		p->tr2 = NULL;	return(p);}tconst(val, type){	register struct tconst *p;	p = getblk(sizeof(*p));	p->op = CON;	p->type = type;	p->value = val;	return(p);}getblk(size){	register *p;	if (size&01)		abort();	p = curbase;	if ((curbase =+ size) >= coremax) {		if (sbrk(1024) == -1) {			error("Out of space-- c1");			exit(1);		}		coremax =+ 1024;	}	return(p);}islong(t){	if (t==LONG)		return(2);	return(1);}isconstant(at)struct tnode *at;{	register struct tnode *t;	t = at;	if (t->op==CON || t->op==SFCON)		return(t);	if (t->op==ITOL && t->tr1->op==CON)		return(t->tr1);	return(0);}hardlongs(at)struct tnode *at;{	register struct tnode *t;	t = at;	switch(t->op) {	case TIMES:	case DIVIDE:	case MOD:		t->op =+ LTIMES-TIMES;		break;	case ASTIMES:	case ASDIV:	case ASMOD:		t->op =+ LASTIMES-ASTIMES;		t->tr1 = tnode(AMPER, LONG+PTR, t->tr1);		break;	default:		return(t);	}	return(optim(t));}

⌨️ 快捷键说明

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