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

📄 c10.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
		goto subtre;	/* H */	case 'H':		p = tree;		flag = 04;	subtre:		ctable = regtab;		if (flag&04)			ctable = cregtab;		c = *string++ - 'A';		if (*string=='!') {			string++;			c =| 020;	/* force right register */		}		if ((c&02)!=0)			ctable = sptab;		if ((c&04)!=0)			ctable = cctab;		if ((flag&01) && ctable==regtab && (c&01)==0		  && (tree->op==DIVIDE||tree->op==MOD		   || tree->op==ASDIV||tree->op==ASMOD||tree->op==ITOL))			ctable = cregtab;		if ((c&01)!=0) {			p = p->tr1;			if(collcon(p) && ctable!=sptab) {				if (p->op==STAR)					p = p->tr1;				p = p->tr1;			}		}		if (table==lsptab && ctable==sptab)			ctable = lsptab;		if (c&010)			r = reg1;		else			if (opdope[p->op]&LEAF || p->degree < 2)				r = reg;			else				r = areg;		rreg = rcexpr(p, ctable, r);		if (ctable!=regtab && ctable!=cregtab)			goto loop;		if (c&010) {			if (c&020 && rreg!=reg1)				movreg(rreg, reg1, p);			else				reg1 = rreg;		} else if (rreg!=reg)			if ((c&020)==0 && oddreg(tree, 0)==0 && tree->type!=LONG			&& (flag&04			  || flag&01&&xdcalc(p2,nreg-rreg-1)<=(opt->tabdeg2&077)			  || flag&02&&xdcalc(p1,nreg-rreg-1)<=(opt->tabdeg1&077))) {				reg = rreg;				reg1 = rreg+1;			} else				movreg(rreg, reg, p);		goto loop;	/* R */	case 'I':		r = reg;		if (*string=='-') {			string++;			r--;		}		goto preg;	/* R1 */	case 'J':		r = reg1;	preg:		if (*string=='+') {			string++;			r++;		}		if (r>nreg || r>=4 && tree->type==DOUBLE)			error("Register overflow: simplify expression");		printf("r%d", r);		goto loop;	case '-':		/* check -(sp) */		if (*string=='(') {			nstack++;			if (table!=lsptab)				putchar('-');			goto loop;		}		break;	case ')':		/* check (sp)+ */		putchar(')');		if (*string=='+')			nstack--;		goto loop;	/* #1 */	case '#':		p = p1->tr1;		goto nmbr;	/* #2 */	case '"':		p = p2->tr1;	nmbr:		if(collcon(p)) {			if (p->op==STAR) {				printf("*");				p = p->tr1;			}			if ((p = p->tr2)->op == CON) {				if (p->value)					psoct(p->value);			} else if (p->op==AMPER)				pname(p->tr1, 0);		}		goto loop;	/*	 * Certain adjustments for / % and PTOI	 */	case 'T':		c = reg-1;		if (tree->op == PTOI) {			printf("bic	r%d,r%d\nsbc	r%d\n", c,c,c);			goto loop;		}		if (p1->type==UNSIGN || p1->type&XTYPE) {			printf("clr	r%d\n", c);			goto loop;		}		if (dcalc(p1, 5)>12 && !match(p1, cctab, 10, 0))			printf("tst	r%d\n", reg);		printf("sxt	r%d\n", c);		goto loop;	case 'V':	/* adc sbc, clr, or sxt as required for longs */		switch(tree->op) {		case PLUS:		case ASPLUS:		case INCBEF:		case INCAFT:			printf("adc");			break;		case MINUS:		case ASMINUS:		case NEG:		case DECBEF:		case DECAFT:			printf("sbc");			break;		case ASSIGN:			p = tree->tr2;			goto lcasev;		case ASDIV:		case ASMOD:		case ASULSH:			p = tree->tr1;		lcasev:			if (p->type!=LONG) {				if (p->type==UNSIGN || p->type&XTYPE)					printf("clr");				else					printf("sxt");				goto loop;			}		default:			while ((c = *string++)!='\n' && c!='\0');			break;		}		goto loop;	/*	 * Mask used in field assignments	 */	case 'Z':		printf("$%o", tree->mask);		goto loop;	/*	 * Relational on long values.	 * Might bug out early. E.g.,	 * (long<0) can be determined with only 1 test.	 */	case 'X':		if (xlongrel(*string++ - '0'))			return(reg);		goto loop;	}	putchar(c);	goto loop;}/* * This routine just calls sreorder (below) * on the subtrees and then on the tree itself. * It returns non-zero if anything changed. */reorder(treep, table, reg)struct tnode **treep;struct table *table;{	register r, o;	register struct tnode *p;	p = *treep;	o = p->op;	if (opdope[o]&LEAF || o==LOGOR || o==LOGAND)		return(0);	while(sreorder(&p->tr1, regtab, reg, 1))		;	if (opdope[o]&BINARY) 		while(sreorder(&p->tr2, regtab, reg, 1))			;	r = 0;	if (table!=cctab)	while (sreorder(treep, table, reg, 0))		r++;	*treep = optim(*treep);	return(r);}/* * Basically this routine carries out two kinds of optimization. * First, it observes that "x + (reg = y)" where actually * the = is any assignment op is better done as "reg=y; x+reg". * In this case rcexpr is called to do the first part and the * tree is modified so the name of the register * replaces the assignment. * Moreover, expressions like "reg = x+y" are best done as * "reg = x; reg =+ y" (so long as "reg" and "y" are not the same!). */sreorder(treep, table, reg, recurf)struct tnode **treep;struct table *table;{	register struct tnode *p, *p1;	p = *treep;	if (opdope[p->op]&LEAF)		return(0);	if (p->op==PLUS && recurf)		if (reorder(&p->tr2, table, reg))			*treep = p = optim(p);	p1 = p->tr1;	if (p->op==STAR || p->op==PLUS) {		if (recurf && reorder(&p->tr1, table, reg))			*treep = p = optim(p);		p1 = p->tr1;	}	if (p1->op==NAME) switch(p->op) {		case ASLSH:		case ASRSH:		case ASSIGN:			if (p1->class != REG||p1->type==CHAR||isfloat(p->tr2))				return(0);			if (p->op==ASSIGN) switch (p->tr2->op) {			case TIMES:				if (!ispow2(p->tr2))					break;				p->tr2 = pow2(p->tr2);			case PLUS:			case MINUS:			case AND:			case ANDN:			case OR:			case EXOR:			case LSHIFT:			case RSHIFT:				p1 = p->tr2->tr2;				if (xdcalc(p1, 16) > 12				 || p1->op==NAME				 &&(p1->nloc==p->tr1->nloc				  || p1->regno==p->tr1->nloc))					return(0);				p1 = p->tr2;				p->tr2 = p1->tr1;				if (p1->tr1->op!=NAME				 || p1->tr1->class!=REG				 || p1->tr1->nloc!=p->tr1->nloc)					rcexpr(p, efftab, reg);				p->tr2 = p1->tr2;				p->op = p1->op + ASPLUS - PLUS;				*treep = p;				return(1);			}			goto OK;		case ASTIMES:			if (!ispow2(p))				return(0);		case ASPLUS:		case ASMINUS:		case ASAND:		case ASANDN:		case ASOR:		case ASXOR:		case INCBEF:		case DECBEF:		OK:			if (table==cctab||table==cregtab)				reg =+ 020;			rcexpr(optim(p), efftab, ~reg);			*treep = p1;			return(1);	}	return(0);}/* * Delay handles postfix ++ and --  * It observes that "x + y++" is better * treated as "x + y; y++". * If the operator is ++ or -- itself, * it calls rcexpr to load the operand, letting * the calling instance of rcexpr to do the * ++ using efftab. * Otherwise it uses sdelay to search for inc/dec * among the operands. */delay(treep, table, reg)struct tnode **treep;{	register struct tnode *p, *p1;	register r;	p = *treep;	if ((p->op==INCAFT||p->op==DECAFT)	 && p->tr1->op==NAME) {		return(1+rcexpr(p->tr1, table, reg));	}	p1 = 0;	if (opdope[p->op]&BINARY) {		if (p->op==LOGAND || p->op==LOGOR)			return(0);		}		p1 = sdelay(&p->tr2);	if (p1==0)		p1 = sdelay(&p->tr1);	if (p1) {		r = rcexpr(optim(p), table, reg);		*treep = p1;		return(r+1);	}	return(0);}sdelay(ap)struct tnode **ap;{	register struct tnode *p, *p1;	p = *ap;	if ((p->op==INCAFT||p->op==DECAFT) && p->tr1->op==NAME) {		*ap = ncopy(p->tr1);		return(p);	}	if (p->op==STAR || p->op==PLUS)		if (p1=sdelay(&p->tr1))			return(p1);	if (p->op==PLUS)		return(sdelay(&p->tr2));	return(0);}/* * Copy a tree node for a register variable. * Used by sdelay because if *reg-- is turned * into *reg; reg-- the *reg will in turn * be changed to some offset class, accidentally * modifying the reg--. */ncopy(ap)struct tname *ap;{	register struct tname *p, *q;	p = ap;	if (p->class!=REG)		return(p);	q = getblk(sizeof(*p));	q->op = p->op;	q->type = p->type;	q->class = p->class;	q->offset = p->offset;	q->nloc = p->nloc;	return(q);}/* * If the tree can be immediately loaded into a register, * produce code to do so and return success. */chkleaf(atree, table, reg)struct tnode *atree;{	struct tnode lbuf;	register struct tnode *tree;	tree = atree;	if (tree->op!=STAR && dcalc(tree, nreg-reg) > 12)		return(-1);	lbuf.op = LOAD;	lbuf.type = tree->type;	lbuf.degree = tree->degree;	lbuf.tr1 = tree;	return(rcexpr(&lbuf, table, reg));}/* * Compile a function argument. * If the stack is currently empty, put it in (sp) * rather than -(sp); this will save a pop. * Return the number of bytes pushed, * for future popping. */comarg(atree, flagp)int *flagp;{	register struct tnode *tree;	register retval;	int i;	int size;	tree = atree;	if (tree->op==STRASG) {		size = tree->mask;		tree = tree->tr1;		tree = strfunc(tree);		if (size <= 2) {			setype(tree, INT);			goto normal;		}		if (size <= 4) {			setype(tree, LONG);			goto normal;		}		if (tree->op!=NAME && tree->op!=STAR) {			error("Unimplemented structure assignment");			return(0);		}		tree = tnode(AMPER, STRUCT+PTR, tree);		tree = tnode(PLUS, STRUCT+PTR, tree, tconst(size, INT));		tree = optim(tree);		retval = rcexpr(tree, regtab, 0);		size =>> 1;		if (size <= 5) {			for (i=0; i<size; i++)				printf("mov	-(r%d),-(sp)\n", retval);		} else {			if (retval!=0)				printf("mov	r%d,r0\n", retval);			printf("mov	$%o,r1\n", size);			printf("L%d:mov	-(r0),-(sp)\ndec\tr1\njne\tL%d\n", isn, isn);			isn++;		}		nstack++;		return(size*2);	}normal:	if (nstack || isfloat(tree) || tree->type==LONG) {		rcexpr(tree, sptab, 0);		retval = arlength(tree->type);	} else {		(*flagp)++;		rcexpr(tree, lsptab, 0);		retval = 0;	}	return(retval);}struct tnode *strfunc(atp)struct tnode *atp;{	register struct tnode *tp;	tp = atp;	if (tp->op != CALL)		return(tp);	setype(tp, STRUCT+PTR);	return(tnode(STAR, STRUCT, tp));}/* * Compile an initializing expression */doinit(atype, atree)struct tnode *atree;{	register struct tnode *tree;	register int type;	float sfval;	double fval;	long lval;	tree = atree;	type = atype;	if (type==CHAR) {		printf(".byte ");		if (tree->type&XTYPE)			goto illinit;		type = INT;	}	if (type&XTYPE)		type = INT;	switch (type) {	case INT:	case UNSIGN:		if (tree->op==FTOI) {			if (tree->tr1->op!=FCON && tree->tr1->op!=SFCON)				goto illinit;			tree = tree->tr1;			tree->value = tree->fvalue;			tree->op = CON;		} else if (tree->op==LTOI) {			if (tree->tr1->op!=LCON)				goto illinit;			tree = tree->tr1;			lval = tree->lvalue;			tree->op = CON;			tree->value = lval;		}		if (tree->op == CON)			printf("%o\n", tree->value);		else if (tree->op==AMPER) {			pname(tree->tr1, 0);			putchar('\n');		} else			goto illinit;		return;	case DOUBLE:	case FLOAT:		if (tree->op==ITOF) {			if (tree->tr1->op==CON) {				fval = tree->tr1->value;			} else				goto illinit;		} else if (tree->op==FCON || tree->op==SFCON)			fval = tree->fvalue;		else if (tree->op==LTOF) {			if (tree->tr1->op!=LCON)				goto illinit;			fval = tree->tr1->lvalue;		} else			goto illinit;		if (type==FLOAT) {			sfval = fval;			printf("%o; %o\n", sfval);		} else			printf("%o; %o; %o; %o\n", fval);		return;	case LONG:		if (tree->op==FTOL) {			tree = tree->tr1;			if (tree->op==SFCON)				tree->op = FCON;			if (tree->op!= FCON)				goto illinit;			lval = tree->fvalue;		} else if (tree->op==ITOL) {			if (tree->tr1->op != CON)				goto illinit;			lval = tree->tr1->value;		} else if (tree->op==LCON)			lval = tree->lvalue;		else			goto illinit;		printf("%o; %o\n", lval);		return;	}illinit:	error("Illegal initialization");}movreg(r0, r1, tree)struct tnode *tree;{	register char *s;	if (r0==r1)		return;	if (tree->type==LONG) {		s = "mov	r%d,r%d\nmov	r%d,r%d\n";		if (r0 < r1)			printf(s, r0+1,r1+1,r0,r1);		else			printf(s, r0,r1,r0+1,r1+1);		return;	}	printf("mov%c	r%d,r%d\n", isfloat(tree), r0, r1);}

⌨️ 快捷键说明

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