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

📄 c11.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
#/* *  C compiler */#include "c1.h"max(a, b){	if (a>b)		return(a);	return(b);}degree(at)struct tnode *at;{	register struct tnode *t, *t1;	if ((t=at)==0 || t->op==0)		return(0);	if (t->op == CON)		return(-3);	if (t->op == AMPER)		return(-2);	if (t->op==ITOL) {		if ((t1 = isconstant(t)) && (t1->value>=0 || t1->type==UNSIGN))			return(-2);		if ((t1=t->tr1)->type==UNSIGN && opdope[t1->op]&LEAF)			return(-1);	}	if ((opdope[t->op] & LEAF) != 0) {		if (t->type==CHAR || t->type==FLOAT)			return(1);		return(0);	}	return(t->degree);}pname(ap, flag)struct tnode *ap;{	register i;	register struct tnode *p;	struct { int intx[2]; };	p = ap;loop:	switch(p->op) {	case LCON:		printf("$%o", flag>10? p->lvalue.intx[1]:p->lvalue.intx[0]);		return;	case SFCON:	case CON:		printf("$");		psoct(p->value);		return;	case FCON:		printf("L%d", (p->value>0? p->value: -p->value));		return;	case NAME:		i = p->offset;		if (flag>10)			i =+ 2;		if (i) {			psoct(i);			if (p->class!=OFFS)				putchar('+');			if (p->class==REG)				regerr();		}		switch(p->class) {		case SOFFS:		case XOFFS:			pbase(p);		case OFFS:			printf("(r%d)", p->regno);			return;		case EXTERN:		case STATIC:			pbase(p);			return;		case REG:			printf("r%d", p->nloc);			return;		}		error("Compiler error: pname");		return;	case AMPER:		putchar('$');		p = p->tr1;		if (p->op==NAME && p->class==REG)			regerr();		goto loop;	case AUTOI:		printf("(r%d)%c", p->nloc, flag==1?0:'+');		return;	case AUTOD:		printf("%c(r%d)", flag==2?0:'-', p->nloc);		return;	case STAR:		p = p->tr1;		putchar('*');		goto loop;	}	error("pname called illegally");}regerr(){	error("Illegal use of register");}pbase(ap)struct tnode *ap;{	register struct tnode *p;	p = ap;	if (p->class==SOFFS || p->class==STATIC)		printf("L%d", p->nloc);	else		printf("%.8s", &(p->nloc));}xdcalc(ap, nrleft)struct tnode *ap;{	register struct tnode *p;	register d;	p = ap;	d = dcalc(p, nrleft);	if (d<20 && p->type==CHAR) {		if (nrleft>=1)			d = 20;		else			d = 24;	}	return(d);}dcalc(ap, nrleft)struct tnode *ap;{	register struct tnode *p, *p1;	if ((p=ap)==0)		return(0);	switch (p->op) {	case NAME:		if (p->class==REG)			return(9);	case AMPER:	case FCON:	case LCON:	case AUTOI:	case AUTOD:		return(12);	case CON:	case SFCON:		if (p->value==0)			return(4);		if (p->value==1)			return(5);		if (p->value > 0)			return(8);		return(12);	case STAR:		p1 = p->tr1;		if (p1->op==NAME||p1->op==CON||p1->op==AUTOI||p1->op==AUTOD)			if (p->type!=LONG)				return(12);	}	if (p->type==LONG)		nrleft--;	return(p->degree <= nrleft? 20: 24);}notcompat(ap, ast, op)struct tnode *ap;{	register at, st;	register struct tnode *p;	p = ap;	at = p->type;	st = ast;	if (st==0)		/* word, byte */		return(at!=CHAR && at!=INT && at!=UNSIGN && at<PTR);	if (st==1)		/* word */		return(at!=INT && at!=UNSIGN && at<PTR);	if (st==9 && (at&XTYPE))		return(0);	st =- 2;	if ((at&(~(TYPE+XTYPE))) != 0)		at = 020;	if ((at&(~TYPE)) != 0)		at = at&TYPE | 020;	if (st==FLOAT && at==DOUBLE)		at = FLOAT;	if (p->op==NAME && p->class==REG && op==ASSIGN && st==CHAR)		return(0);	return(st != at);}prins(op, c, itable)struct instab *itable;{	register struct instab *insp;	register char *ip;	for (insp=itable; insp->op != 0; insp++) {		if (insp->op == op) {			ip = c? insp->str2: insp->str1;			if (ip==0)				break;			printf("%s", ip);			return;		}	}	error("No match' for op %d", op);}collcon(ap)struct tnode *ap;{	register op;	register struct tnode *p;	p = ap;	if (p->op==STAR) {		if (p->type==LONG+PTR) /* avoid *x(r); *x+2(r) */			return(0);		p = p->tr1;	}	if (p->op==PLUS) {		op = p->tr2->op;		if (op==CON || op==AMPER)			return(1);	}	return(0);}isfloat(at)struct tnode *at;{	register struct tnode *t;	t = at;	if ((opdope[t->op]&RELAT)!=0)		t = t->tr1;	if (t->type==FLOAT || t->type==DOUBLE) {		nfloat = 1;		return('f');	}	return(0);}oddreg(t, areg)struct tnode *t;{	register reg;	reg = areg;	if (!isfloat(t)) {		if (opdope[t->op]&RELAT) {			if (t->tr1->type==LONG)				return((reg+1) & ~01);			return(reg);		}		switch(t->op) {		case LLSHIFT:		case ASLSHL:			return((reg+1)&~01);		case DIVIDE:		case MOD:		case ASDIV:		case ASMOD:		case PTOI:		case ULSH:		case ASULSH:			reg++;		case TIMES:		case ASTIMES:			return(reg|1);		}	}	return(reg);}arlength(t){	if (t>=PTR)		return(2);	switch(t) {	case INT:	case CHAR:	case UNSIGN:		return(2);	case LONG:		return(4);	case FLOAT:	case DOUBLE:		return(8);	}	return(1024);}/* * Strings for switch code. */char	dirsw[] {"\cmp	r0,$%o\n\jhi	L%d\n\asl	r0\n\jmp	*L%d(r0)\n\.data\n\L%d:\" };char	hashsw[] {"\mov	r0,r1\n\clr	r0\n\div	$%o,r0\n\asl	r1\n\jmp	*L%d(r1)\n\.data\n\L%d:\"};/* * If the unsigned casts below won't compile, * try using the calls to lrem and ldiv. */pswitch(afp, alp, deflab)struct swtab *afp, *alp;{	int ncase, i, j, tabs, worst, best, range;	register struct swtab *swp, *fp, *lp;	int *poctab;	fp = afp;	lp = alp;	if (fp==lp) {		printf("jbr	L%d\n", deflab);		return;	}	isn++;	if (sort(fp, lp))		return;	ncase = lp-fp;	lp--;	range = lp->swval - fp->swval;	/* direct switch */	if (range>0 && range <= 3*ncase) {		if (fp->swval)			printf("sub	$%o,r0\n", fp->swval);		printf(dirsw, range, deflab, isn, isn);		isn++;		for (i=fp->swval; ; i++) {			if (i==fp->swval) {				printf("L%d\n", fp->swlab);				if (fp==lp)					break;				fp++;			} else				printf("L%d\n", deflab);		}		printf(".text\n");		return;	}	/* simple switch */	if (ncase<10) {		for (fp = afp; fp<=lp; fp++)			breq(fp->swval, fp->swlab);		printf("jbr	L%d\n", deflab);		return;	}	/* hash switch */	best = 077777;	poctab = getblk(((ncase+2)/2) * sizeof(*poctab));	for (i=ncase/4; i<=ncase/2; i++) {		for (j=0; j<i; j++)			poctab[j] = 0;		for (swp=fp; swp<=lp; swp++)			/* lrem(0, swp->swval, i) */			poctab[(unsigned)swp->swval%i]++;		worst = 0;		for (j=0; j<i; j++)			if (poctab[j]>worst)				worst = poctab[j];		if (i*worst < best) {			tabs = i;			best = i*worst;		}	}	i = isn++;	printf(hashsw, tabs, i, i);	isn++;	for (i=0; i<tabs; i++)		printf("L%d\n", isn+i);	printf(".text\n");	for (i=0; i<tabs; i++) {		printf("L%d:", isn++);		for (swp=fp; swp<=lp; swp++) {			/* lrem(0, swp->swval, tabs) */			if ((unsigned)swp->swval%tabs == i) {				/* ldiv(0, swp->swval, tabs) */				breq((unsigned)swp->swval/tabs, swp->swlab);			}		}		printf("jbr	L%d\n", deflab);	}}breq(v, l){	if (v==0)		printf("tst	r0\n");	else		printf("cmp	r0,$%o\n", v);	printf("jeq	L%d\n", l);}sort(afp, alp)struct swtab *afp, *alp;{	register struct swtab *cp, *fp, *lp;	int intch, t;	fp = afp;	lp = alp;	while (fp < --lp) {		intch = 0;		for (cp=fp; cp<lp; cp++) {			if (cp->swval == cp[1].swval) {				error("Duplicate case (%d)", cp->swval);				return(1);			}			if (cp->swval > cp[1].swval) {				intch++;				t = cp->swval;				cp->swval = cp[1].swval;				cp[1].swval = t;				t = cp->swlab;				cp->swlab = cp[1].swlab;				cp[1].swlab = t;			}		}		if (intch==0)			break;	}	return(0);}ispow2(atree){	register int d;	register struct tnode *tree;	tree = atree;	if (!isfloat(tree) && tree->tr2->op==CON) {		d = tree->tr2->value;		if (d>1 && (d&(d-1))==0)			return(d);	}	return(0);}pow2(atree)struct tnode *atree;{	register int d, i;	register struct tnode *tree;	tree = atree;	if (d = ispow2(tree)) {		for (i=0; (d=>>1)!=0; i++);		tree->tr2->value = i;		switch (tree->op) {		case TIMES:			tree->op = LSHIFT;			break;		case ASTIMES:			tree->op = ASLSH;			break;		case DIVIDE:			tree->op = ULSH;			tree->tr2->value = -i;			break;		case ASDIV:			tree->op = ASULSH;			tree->tr2->value = -i;			break;		case MOD:			tree->op = AND;			tree->tr2->value = (1<<i)-1;			break;		case ASMOD:			tree->op = ASAND;			tree->tr2->value = (1<<i)-1;			break;		default:			error("pow2 botch");		}		tree = optim(tree);	}	return(tree);}cbranch(atree, albl, cond, areg)struct tnode *atree;{	int l1, op;	register lbl, reg;	register struct tnode *tree;	lbl = albl;	reg = areg;again:	if ((tree=atree)==0)		return;	switch(tree->op) {	case LOGAND:		if (cond) {			cbranch(tree->tr1, l1=isn++, 0, reg);			cbranch(tree->tr2, lbl, 1, reg);			label(l1);		} else {			cbranch(tree->tr1, lbl, 0, reg);			cbranch(tree->tr2, lbl, 0, reg);		}		return;	case LOGOR:		if (cond) {			cbranch(tree->tr1, lbl, 1, reg);			cbranch(tree->tr2, lbl, 1, reg);		} else {			cbranch(tree->tr1, l1=isn++, 1, reg);			cbranch(tree->tr2, lbl, 0, reg);			label(l1);		}		return;	case EXCLA:		cbranch(tree->tr1, lbl, !cond, reg);		return;	case SEQNC:

⌨️ 快捷键说明

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