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

📄 sub.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	if(k == TIND) {		if(i == TIND)			n->type = t1;		else		if(j == TIND)			n->type = t2;	} else {		/* convert up to at least int */		if(f == 1)		while(k < TINT)			k += 2;		n->type = types[k];	}	if(n->op == OSUB)	if(i == TIND && j == TIND) {		w = n->right->type->link->width;		if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1)			goto bad;		n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG];		if(1 && ewidth[TIND] > ewidth[TLONG]){			n1 = new1(OXXX, Z, Z);			*n1 = *n;			n->op = OCAST;			n->left = n1;			n->right = Z;			n->type = types[TLONG];		}		if(w > 1) {			n1 = new1(OXXX, Z, Z);			*n1 = *n;			n->op = ODIV;			n->left = n1;			n1 = new1(OCONST, Z, Z);			n1->vconst = w;			n1->type = n->type;			n->right = n1;			w = vlog(n1);			if(w >= 0) {				n->op = OASHR;				n1->vconst = w;			}		}		return;	}	if(!sametype(n->type, n->left->type)) {		n->left = new1(OCAST, n->left, Z);		n->left->type = n->type;		if(n->type->etype == TIND) {			w = n->type->link->width;			if(w < 1) {				snap(n->type->link);				w = n->type->link->width;				if(w < 1)					goto bad;			}			if(w > 1) {				n1 = new1(OCONST, Z, Z);				n1->vconst = w;				n1->type = n->type;				n->left = new1(OMUL, n->left, n1);				n->left->type = n->type;			}		}	}	if(n->right != Z)	if(!sametype(n->type, n->right->type)) {		n->right = new1(OCAST, n->right, Z);		n->right->type = n->type;		if(n->type->etype == TIND) {			w = n->type->link->width;			if(w < 1) {				snap(n->type->link);				w = n->type->link->width;				if(w < 1)					goto bad;			}			if(w != 1) {				n1 = new1(OCONST, Z, Z);				n1->vconst = w;				n1->type = n->type;				n->right = new1(OMUL, n->right, n1);				n->right->type = n->type;			}		}	}	return;bad:	diag(n, "pointer addition not fully declared: %T", n->type->link);}/* * try to rewrite shift & mask */voidsimplifyshift(Node *n){	ulong c3;	int o, s1, s2, c1, c2;	if(!typechlp[n->type->etype])		return;	switch(n->op) {	default:		return;	case OASHL:		s1 = 0;		break;	case OLSHR:		s1 = 1;		break;	case OASHR:		s1 = 2;		break;	}	if(n->right->op != OCONST)		return;	if(n->left->op != OAND)		return;	if(n->left->right->op != OCONST)		return;	switch(n->left->left->op) {	default:		return;	case OASHL:		s2 = 0;		break;	case OLSHR:		s2 = 1;		break;	case OASHR:		s2 = 2;		break;	}	if(n->left->left->right->op != OCONST)		return;	c1 = n->right->vconst;	c2 = n->left->left->right->vconst;	c3 = n->left->right->vconst;/*	if(debug['h'])		print("%.3o %ld %ld %d #%.lux\n",			(s1<<3)|s2, c1, c2, topbit(c3), c3);*/	o = n->op;	switch((s1<<3)|s2) {	case 000:	/* (((e <<u c2) & c3) <<u c1) */		c3 >>= c2;		c1 += c2;		if(c1 >= 32)			break;		goto rewrite1;	case 002:	/* (((e >>s c2) & c3) <<u c1) */		if(topbit(c3) >= (32-c2))			break;	case 001:	/* (((e >>u c2) & c3) <<u c1) */		if(c1 > c2) {			c3 <<= c2;			c1 -= c2;			o = OASHL;			goto rewrite1;		}		c3 <<= c1;		if(c1 == c2)			goto rewrite0;		c1 = c2-c1;		o = OLSHR;		goto rewrite2;	case 022:	/* (((e >>s c2) & c3) >>s c1) */		if(c2 <= 0)			break;	case 012:	/* (((e >>s c2) & c3) >>u c1) */		if(topbit(c3) >= (32-c2))			break;		goto s11;	case 021:	/* (((e >>u c2) & c3) >>s c1) */		if(topbit(c3) >= 31 && c2 <= 0)			break;		goto s11;	case 011:	/* (((e >>u c2) & c3) >>u c1) */	s11:		c3 <<= c2;		c1 += c2;		if(c1 >= 32)			break;		o = OLSHR;		goto rewrite1;	case 020:	/* (((e <<u c2) & c3) >>s c1) */		if(topbit(c3) >= 31)			break;	case 010:	/* (((e <<u c2) & c3) >>u c1) */		c3 >>= c1;		if(c1 == c2)			goto rewrite0;		if(c1 > c2) {			c1 -= c2;			goto rewrite2;		}		c1 = c2 - c1;		o = OASHL;		goto rewrite2;	}	return;rewrite0:	/* get rid of both shifts */if(debug['<'])prtree(n, "rewrite0");	*n = *n->left;	n->left = n->left->left;	n->right->vconst = c3;	return;rewrite1:	/* get rid of lower shift */if(debug['<'])prtree(n, "rewrite1");	n->left->left = n->left->left->left;	n->left->right->vconst = c3;	n->right->vconst = c1;	n->op = o;	return;rewrite2:	/* get rid of upper shift */if(debug['<'])prtree(n, "rewrite2");	*n = *n->left;	n->right->vconst = c3;	n->left->right->vconst = c1;	n->left->op = o;}intside(Node *n){loop:	if(n != Z)	switch(n->op) {	case OCAST:	case ONOT:	case OADDR:	case OIND:		n = n->left;		goto loop;	case OCOND:		if(side(n->left))			break;		n = n->right;	case OEQ:	case ONE:	case OLT:	case OGE:	case OGT:	case OLE:	case OADD:	case OSUB:	case OMUL:	case OLMUL:	case ODIV:	case OLDIV:	case OLSHR:	case OASHL:	case OASHR:	case OAND:	case OOR:	case OXOR:	case OMOD:	case OLMOD:	case OANDAND:	case OOROR:	case OCOMMA:	case ODOT:		if(side(n->left))			break;		n = n->right;		goto loop;	case OSIGN:	case OSIZE:	case OCONST:	case OSTRING:	case OLSTRING:	case ONAME:		return 0;	}	return 1;}intvconst(Node *n){	int i;	if(n == Z)		goto no;	if(n->op != OCONST)		goto no;	if(n->type == T)		goto no;	switch(n->type->etype)	{	case TFLOAT:	case TDOUBLE:		i = 100;		if(n->fconst > i || n->fconst < -i)			goto no;		i = n->fconst;		if(i != n->fconst)			goto no;		return i;	case TVLONG:	case TUVLONG:		i = n->vconst;		if(i != n->vconst)			goto no;		return i;	case TCHAR:	case TUCHAR:	case TSHORT:	case TUSHORT:	case TINT:	case TUINT:	case TLONG:	case TULONG:	case TIND:		i = n->vconst;		if(i != n->vconst)			goto no;		return i;	}no:	return -159;	/* first uninteresting constant */}/* * return log(n) if n is a power of 2 constant */intlog2(uvlong v){	int s, i;	uvlong m;	s = 0;	m = MASK(8*sizeof(uvlong));	for(i=32; i; i>>=1) {		m >>= i;		if(!(v & m)) {			v >>= i;			s += i;		}	}	if(v == 1)		return s;	return -1;}intvlog(Node *n){	if(n->op != OCONST)		goto bad;	if(typefd[n->type->etype])		goto bad;	return log2(n->vconst);bad:	return -1;}inttopbit(ulong v){	int i;	for(i = -1; v; i++)		v >>= 1;	return i;}/* * try to cast a constant down * rather than cast a variable up * example: *	if(c == 'a') */voidrelcon(Node *l, Node *r){	vlong v;	if(l->op != OCONST)		return;	if(r->op != OCAST)		return;	if(!nilcast(r->left->type, r->type))		return;	switch(r->type->etype) {	default:		return;	case TCHAR:	case TUCHAR:	case TSHORT:	case TUSHORT:		v = convvtox(l->vconst, r->type->etype);		if(v != l->vconst)			return;		break;	}	l->type = r->left->type;	*r = *r->left;}intrelindex(int o){	switch(o) {	default:		diag(Z, "bad in relindex: %O", o);	case OEQ: return 0;	case ONE: return 1;	case OLE: return 2;	case OLS: return 3;	case OLT: return 4;	case OLO: return 5;	case OGE: return 6;	case OHS: return 7;	case OGT: return 8;	case OHI: return 9;	}}Node*invert(Node *n){	Node *i;	if(n == Z || n->op != OLIST)		return n;	i = n;	for(n = n->left; n != Z; n = n->left) {		if(n->op != OLIST)			break;		i->left = n->right;		n->right = i;		i = n;	}	i->left = n;	return i;}intbitno(long b){	int i;	for(i=0; i<32; i++)		if(b & (1L<<i))			return i;	diag(Z, "bad in bitno");	return 0;}longtypebitor(long a, long b){	long c;	c = a | b;	if(a & b)		if((a & b) == BLONG)			c |= BVLONG;		/* long long => vlong */		else			warn(Z, "once is enough: %Q", a & b);	return c;}voiddiag(Node *n, char *fmt, ...){	char buf[STRINGSZ];	va_list arg;	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);	if(debug['X']){		Bflush(&diagbuf);		abort();	}	if(n != Z)	if(debug['v'])		prtree(n, "diagnostic");	nerrors++;	if(nerrors > 10) {		Bprint(&diagbuf, "too many errors\n");		errorexit();	}}voidwarn(Node *n, char *fmt, ...){	char buf[STRINGSZ];	va_list arg;	if(debug['w']) {		Bprint(&diagbuf, "warning: ");		va_start(arg, fmt);		vseprint(buf, buf+sizeof(buf), fmt, arg);		va_end(arg);		Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);		if(n != Z)		if(debug['v'])			prtree(n, "warning");	}}voidyyerror(char *fmt, ...){	char buf[STRINGSZ];	va_list arg;	/*	 * hack to intercept message from yaccpar	 */	if(strcmp(fmt, "syntax error") == 0) {		yyerror("syntax error, last name: %s", symb);		return;	}	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	Bprint(&diagbuf, "%L %s\n", lineno, buf);	nerrors++;	if(nerrors > 10) {		Bprint(&diagbuf, "too many errors\n");		errorexit();	}}voidfatal(Node *n, char *fmt, ...){	char buf[STRINGSZ];	va_list arg;	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);	if(debug['X']){		Bflush(&diagbuf);		abort();	}	if(n != Z)	if(debug['v'])		prtree(n, "diagnostic");	nerrors++;	errorexit();}ulong	thash1	= 0x2edab8c9;ulong	thash2	= 0x1dc74fb8;ulong	thash3	= 0x1f241331;ulong	thash[NALLTYPES];Init	thashinit[] ={	TXXX,		0x17527bbd,	0,	TCHAR,		0x5cedd32b,	0,	TUCHAR,		0x552c4454,	0,	TSHORT,		0x63040b4b,	0,	TUSHORT,	0x32a45878,	0,	TINT,		0x4151d5bd,	0,	TUINT,		0x5ae707d6,	0,	TLONG,		0x5ef20f47,	0,	TULONG,		0x36d8eb8f,	0,	TVLONG,		0x6e5e9590,	0,	TUVLONG,	0x75910105,	0,	TFLOAT,		0x25fd7af1,	0,	TDOUBLE,	0x7c40a1b2,	0,	TIND,		0x1b832357,	0,	TFUNC,		0x6babc9cb,	0,	TARRAY,		0x7c50986d,	0,	TVOID,		0x44112eff,	0,	TSTRUCT,	0x7c2da3bf,	0,	TUNION,		0x3eb25e98,	0,	TENUM,		0x44b54f61,	0,	TFILE,		0x19242ac3,	0,	TOLD,		0x22b15988,	0,	TDOT,		0x0204f6b3,	0,	-1,		0,		0,};char*	bnames[NALIGN];Init	bnamesinit[] ={	Axxx,	0,	"Axxx",	Ael1,	0,	"el1",	Ael2,	0,	"el2",	Asu2,	0,	"su2",	Aarg0,	0,	"arg0",	Aarg1,	0,	"arg1",	Aarg2,	0,	"arg2",	Aaut3,	0,	"aut3",	-1,	0,	0,};char*	tnames[NALLTYPES];Init	tnamesinit[] ={	TXXX,		0,	"TXXX",	TCHAR,		0,	"CHAR",	TUCHAR,		0,	"UCHAR",	TSHORT,		0,	"SHORT",	TUSHORT,	0,	"USHORT",	TINT,		0,	"INT",	TUINT,		0,	"UINT",	TLONG,		0,	"LONG",	TULONG,		0,	"ULONG",	TVLONG,		0,	"VLONG",	TUVLONG,	0,	"UVLONG",	TFLOAT,		0,	"FLOAT",	TDOUBLE,	0,	"DOUBLE",	TIND,		0,	"IND",	TFUNC,		0,	"FUNC",	TARRAY,		0,	"ARRAY",	TVOID,		0,	"VOID",	TSTRUCT,	0,	"STRUCT",	TUNION,		0,	"UNION",	TENUM,		0,	"ENUM",	TFILE,		0,	"FILE",	TOLD,		0,	"OLD",	TDOT,		0,	"DOT",	-1,		0,	0,};char*	gnames[NGTYPES];Init	gnamesinit[] ={	GXXX,			0,	"GXXX",	GCONSTNT,		0,	"CONST",	GVOLATILE,		0,	"VOLATILE",	GVOLATILE|GCONSTNT,	0,	"CONST-VOLATILE",	-1,			0,	0,};char*	qnames[NALLTYPES];Init	qnamesinit[] ={	TXXX,		0,	"TXXX",	TCHAR,		0,	"CHAR",	TUCHAR,		0,	"UCHAR",	TSHORT,		0,	"SHORT",	TUSHORT,	0,	"USHORT",	TINT,		0,	"INT",	TUINT,		0,	"UINT",	TLONG,		0,	"LONG",	TULONG,		0,	"ULONG",	TVLONG,		0,	"VLONG",	TUVLONG,	0,	"UVLONG",	TFLOAT,		0,	"FLOAT",	TDOUBLE,	0,	"DOUBLE",

⌨️ 快捷键说明

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