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

📄 c10.c

📁 unix v6 的c compiler 很老了
💻 C
📖 第 1 页 / 共 2 页
字号:
				reg--;		return(reg);	/* A1 */	case 'A':		p = p1;		goto adr;	/* A2 */	case 'B':		p = p2;		goto adr;	adr:		c = 0;		if (*string=='\'') {			c = 1;			string++;		} else if (*string=='+') {			c = 2;			string++;		}		pname(p, c);		goto loop;	/* I */	case 'M':		if ((c = *string)=='\'')			string++;		else			c = 0;		prins(tree->op, c, instab);		goto loop;	/* B1 */	case 'C':		if ((opd&LEAF) != 0)			p = tree;		else			p = p1;		goto pbyte;	/* BF */	case 'P':		p = tree;		goto pb1;	/* B2 */	case 'D':		p = p2;	pbyte:		if (p->type==CHAR)			putchar('b');	pb1:		if (isfloat(p))			putchar('f');		goto loop;	/* BE */	case 'L':		if (p1->type==CHAR || p2->type==CHAR)			putchar('b');		p = tree;		goto pb1;	/* F */	case 'G':		p = p1;		flag = 01;		goto subtre;	/* S */	case 'K':		p = p2;		flag = 02;		goto subtre;	/* H */	case 'H':		p = tree;		flag = 04;	subtre:		ctable = regtab;		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))			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)				printf("mov%c	r%d,r%d\n",				    isfloat(tree),rreg,reg1);			else				reg1 = rreg;		} else if (rreg!=reg)			if ((c&020)==0 && oddreg(tree, 0)==0 && (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				printf("mov%c\tr%d,r%d\n",				    isfloat(tree), rreg, reg);		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)			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;	case 'T':		/* "tst R" if 1st op not in cctab */		if (dcalc(p1, 5)>12 && !match(p1, cctab, 10))			printf("tst	r%d\n", reg);		goto loop;	case 'V':	/* adc or sbc 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;		default:			while ((c = *string++)!='\n' && c!='\0');			break;		}		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, r1;	register struct tnode *p;	p = *treep;	if (opdope[p->op]&LEAF)		return(0);	r1 = 0;	while(sreorder(&p->tr1, table, reg))		r1++;	if (opdope[p->op]&BINARY) 		while(sreorder(&p->tr2, table, reg))			r1++;	r = 0;	while (sreorder(treep, table, reg))		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)struct tnode **treep;struct table *table;{	register struct tnode *p, *p1;	p = *treep;	if (opdope[p->op]&LEAF)		return(0);	if (p->op==PLUS)		if (reorder(&p->tr2, table, reg))			*treep = p = optim(p);	p1 = p->tr1;	if (p->op==STAR || p->op==PLUS) {		if (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 || isfloat(p->tr2))				return(0);			if (p->op==ASSIGN) switch (p->tr2->op) {			case TIMES:			case DIVIDE:				if (!ispow2(p->tr2))					break;				p->tr2 = pow2(p->tr2);			case PLUS:			case MINUS:			case AND:			case NAND:			case OR:			case EXOR:			case LSHIFT:			case RSHIFT:				p1 = p->tr2->tr2;				if (xdcalc(p1) > 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:		case ASDIV:			if (!ispow2(p))				return(0);		case ASPLUS:		case ASMINUS:		case ASSAND:		case ASSNAND:		case ASOR:		case ASXOR:		case DECBEF:		case INCBEF:		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 (table!=efftab && (p->op==INCAFT||p->op==DECAFT)	 && p->tr1->op==NAME) {		return(1+rcexpr(p->tr1, table, reg));	}	p1 = 0;	if (opdope[p->op]&BINARY)		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;	p = ap;	if (p->class!=REG)		return(p);	return(block(3, NAME, p->type, p->elsize, p->tr1,	    p->offset, p->nloc));}/* * 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;	tree = atree;	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);}

⌨️ 快捷键说明

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