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

📄 cgen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
lcgen(Node *n, Node *nn){	Prog *p1;	Node nod;	if(debug['g']) {		prtree(nn, "lcgen lhs");		prtree(n, "lcgen");	}	if(n == Z || n->type == T)		return;	if(nn == Z) {		nn = &nod;		regalloc(&nod, n, Z);	}	switch(n->op) {	default:		if(n->addable < INDEXED) {			diag(n, "unknown op in lcgen: %O", n->op);			break;		}		nod = *n;		nod.op = OADDR;		nod.left = n;		nod.right = Z;		nod.type = types[TIND];		gopcode(OAS, &nod, Z, nn);		break;	case OCOMMA:		cgen(n->left, n->left);		lcgen(n->right, nn);		break;	case OIND:		cgen(n->left, nn);		break;	case OCOND:		bcgen(n->left, 1);		p1 = p;		lcgen(n->right->left, nn);		gbranch(OGOTO);		patch(p1, pc);		p1 = p;		lcgen(n->right->right, nn);		patch(p1, pc);		break;	}}voidbcgen(Node *n, int true){	if(n->type == T)		gbranch(OGOTO);	else		boolgen(n, true, Z);}voidboolgen(Node *n, int true, Node *nn){	int o;	Prog *p1, *p2;	Node *l, *r, nod, nod1;	long curs;	if(debug['g']) {		prtree(nn, "boolgen lhs");		prtree(n, "boolgen");	}	curs = cursafe;	l = n->left;	r = n->right;	switch(n->op) {	default:		if(n->op == OCONST) {			o = vconst(n);			if(!true)				o = !o;			gbranch(OGOTO);			if(o) {				p1 = p;				gbranch(OGOTO);				patch(p1, pc);			}			goto com;		}		regalloc(&nod, n, nn);		cgen(n, &nod);		o = ONE;		if(true)			o = comrel[relindex(o)];		if(typefd[n->type->etype]) {			nodreg(&nod1, n, NREG+FREGZERO);			gopcode(o, &nod, Z, &nod1);		} else			gopcode(o, &nod, Z, nodconst(0));		regfree(&nod);		goto com;	case OCOMMA:		cgen(l, Z);		boolgen(r, true, nn);		break;	case ONOT:		boolgen(l, !true, nn);		break;	case OCOND:		bcgen(l, 1);		p1 = p;		bcgen(r->left, true);		p2 = p;		gbranch(OGOTO);		patch(p1, pc);		p1 = p;		bcgen(r->right, !true);		patch(p2, pc);		p2 = p;		gbranch(OGOTO);		patch(p1, pc);		patch(p2, pc);		goto com;	case OANDAND:		if(!true)			goto caseor;	caseand:		bcgen(l, true);		p1 = p;		bcgen(r, !true);		p2 = p;		patch(p1, pc);		gbranch(OGOTO);		patch(p2, pc);		goto com;	case OOROR:		if(!true)			goto caseand;	caseor:		bcgen(l, !true);		p1 = p;		bcgen(r, !true);		p2 = p;		gbranch(OGOTO);		patch(p1, pc);		patch(p2, pc);		goto com;	case OEQ:	case ONE:	case OLE:	case OLT:	case OGE:	case OGT:	case OHI:	case OHS:	case OLO:	case OLS:		o = n->op;		if(true)			o = comrel[relindex(o)];		if(l->complex >= FNX && r->complex >= FNX) {			regret(&nod, r);			cgen(r, &nod);			regsalloc(&nod1, r);			gopcode(OAS, &nod, Z, &nod1);			regfree(&nod);			nod = *n;			nod.right = &nod1;			boolgen(&nod, true, nn);			break;		}		if(sconst(r)) {			regalloc(&nod, l, nn);			cgen(l, &nod);			gopcode(o, &nod, Z, r);			regfree(&nod);			goto com;		}		if(l->complex >= r->complex) {			regalloc(&nod1, l, nn);			cgen(l, &nod1);			regalloc(&nod, r, Z);			cgen(r, &nod);		} else {			regalloc(&nod, r, nn);			cgen(r, &nod);			regalloc(&nod1, l, Z);			cgen(l, &nod1);		}		gopcode(o, &nod1, Z, &nod);		regfree(&nod);		regfree(&nod1);	com:		if(nn != Z) {			p1 = p;			gopcode(OAS, nodconst(1L), Z, nn);			gbranch(OGOTO);			p2 = p;			patch(p1, pc);			gopcode(OAS, nodconst(0L), Z, nn);			patch(p2, pc);		}		break;	}	cursafe = curs;}voidsugen(Node *n, Node *nn, long w){	Prog *p1;	Node nod0, nod1, nod2, nod3, nod4, *l, *r;	Type *t;	long pc1;	int i, m, c;	if(n == Z || n->type == T)		return;	if(debug['g']) {		prtree(nn, "sugen lhs");		prtree(n, "sugen");	}	if(nn == nodrat)		if(w > nrathole)			nrathole = w;	switch(n->op) {	case OIND:		if(nn == Z) {			nullwarn(n->left, Z);			break;		}	default:		goto copy;	case OCONST:		if(n->type && typev[n->type->etype]) {			if(nn == Z) {				nullwarn(n->left, Z);				break;			}			t = nn->type;			nn->type = types[TLONG];			reglcgen(&nod1, nn, Z);			nn->type = t;			if(align(0, types[TCHAR], Aarg1))	/* isbigendian */				gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);			else				gopcode(OAS, nod32const(n->vconst), Z, &nod1);			nod1.xoffset += SZ_LONG;			if(align(0, types[TCHAR], Aarg1))	/* isbigendian */				gopcode(OAS, nod32const(n->vconst), Z, &nod1);			else				gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);			regfree(&nod1);			break;		}		goto copy;	case ODOT:		l = n->left;		sugen(l, nodrat, l->type->width);		if(nn != Z) {			warn(n, "non-interruptable temporary");			nod1 = *nodrat;			r = n->right;			if(!r || r->op != OCONST) {				diag(n, "DOT and no offset");				break;			}			nod1.xoffset += (long)r->vconst;			nod1.type = n->type;			sugen(&nod1, nn, w);		}		break;	case OSTRUCT:		/*		 * rewrite so lhs has no fn call		 */		if(nn != Z && nn->complex >= FNX) {			nod1 = *n;			nod1.type = typ(TIND, n->type);			regret(&nod2, &nod1);			lcgen(nn, &nod2);			regsalloc(&nod0, &nod1);			gopcode(OAS, &nod2, Z, &nod0);			regfree(&nod2);			nod1 = *n;			nod1.op = OIND;			nod1.left = &nod0;			nod1.right = Z;			nod1.complex = 1;			sugen(n, &nod1, w);			return;		}		r = n->left;		for(t = n->type->link; t != T; t = t->down) {			l = r;			if(r->op == OLIST) {				l = r->left;				r = r->right;			}			if(nn == Z) {				cgen(l, nn);				continue;			}			/*			 * hand craft *(&nn + o) = l			 */			nod0 = znode;			nod0.op = OAS;			nod0.type = t;			nod0.left = &nod1;			nod0.right = l;			nod1 = znode;			nod1.op = OIND;			nod1.type = t;			nod1.left = &nod2;			nod2 = znode;			nod2.op = OADD;			nod2.type = typ(TIND, t);			nod2.left = &nod3;			nod2.right = &nod4;			nod3 = znode;			nod3.op = OADDR;			nod3.type = nod2.type;			nod3.left = nn;			nod4 = znode;			nod4.op = OCONST;			nod4.type = nod2.type;			nod4.vconst = t->offset;			ccom(&nod0);			acom(&nod0);			xcom(&nod0);			nod0.addable = 0;			cgen(&nod0, Z);		}		break;	case OAS:		if(nn == Z) {			if(n->addable < INDEXED)				sugen(n->right, n->left, w);			break;		}		/* BOTCH -- functions can clobber rathole */		sugen(n->right, nodrat, w);		warn(n, "non-interruptable temporary");		sugen(nodrat, n->left, w);		sugen(nodrat, nn, w);		break;	case OFUNC:		if(nn == Z) {			sugen(n, nodrat, w);			break;		}		if(nn->op != OIND) {			nn = new1(OADDR, nn, Z);			nn->type = types[TIND];			nn->addable = 0;		} else			nn = nn->left;		n = new(OFUNC, n->left, new(OLIST, nn, n->right));		n->type = types[TVOID];		n->left->type = types[TVOID];		cgen(n, Z);		break;	case OCOND:		bcgen(n->left, 1);		p1 = p;		sugen(n->right->left, nn, w);		gbranch(OGOTO);		patch(p1, pc);		p1 = p;		sugen(n->right->right, nn, w);		patch(p1, pc);		break;	case OCOMMA:		cgen(n->left, Z);		sugen(n->right, nn, w);		break;	}	return;copy:	if(nn == Z)		return;	if(n->complex >= FNX && nn->complex >= FNX) {		t = nn->type;		nn->type = types[TLONG];		regialloc(&nod1, nn, Z);		lcgen(nn, &nod1);		regsalloc(&nod2, nn);		nn->type = t;		gopcode(OAS, &nod1, Z, &nod2);		regfree(&nod1);		nod2.type = typ(TIND, t);		nod1 = nod2;		nod1.op = OIND;		nod1.left = &nod2;		nod1.right = Z;		nod1.complex = 1;		nod1.type = t;		sugen(n, &nod1, w);		return;	}	if(n->complex > nn->complex) {		t = n->type;		n->type = types[TLONG];		reglcgen(&nod1, n, Z);		n->type = t;		t = nn->type;		nn->type = types[TLONG];		reglcgen(&nod2, nn, Z);		nn->type = t;	} else {		t = nn->type;		nn->type = types[TLONG];		reglcgen(&nod2, nn, Z);		nn->type = t;		t = n->type;		n->type = types[TLONG];		reglcgen(&nod1, n, Z);		n->type = t;	}	w /= SZ_LONG;	if(w <= 5) {		layout(&nod1, &nod2, w, 0, Z);		goto out;	}	/*	 * minimize space for unrolling loop	 * 3,4,5 times. (6 or more is never minimum)	 * if small structure, try 2 also.	 */	c = 0; /* set */	m = 100;	i = 3;	if(w <= 15)		i = 2;	for(; i<=5; i++)		if(i + w%i <= m) {			c = i;			m = c + w%c;		}	regalloc(&nod3, &regnode, Z);	layout(&nod1, &nod2, w%c, w/c, &nod3);		pc1 = pc;	layout(&nod1, &nod2, c, 0, Z);	gopcode(OSUB, nodconst(1L), Z, &nod3);	nod1.op = OREGISTER;	gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);	nod2.op = OREGISTER;	gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);		gopcode(OGT, &nod3, Z, nodconst(0));	patch(p, pc1);	regfree(&nod3);out:	regfree(&nod1);	regfree(&nod2);}voidlayout(Node *f, Node *t, int c, int cv, Node *cn){	Node t1, t2;	while(c > 3) {		layout(f, t, 2, 0, Z);		c -= 2;	}	regalloc(&t1, &regnode, Z);	regalloc(&t2, &regnode, Z);	if(c > 0) {		gopcode(OAS, f, Z, &t1);		f->xoffset += SZ_LONG;	}	if(cn != Z)		gopcode(OAS, nodconst(cv), Z, cn);	if(c > 1) {		gopcode(OAS, f, Z, &t2);		f->xoffset += SZ_LONG;	}	if(c > 0) {		gopcode(OAS, &t1, Z, t);		t->xoffset += SZ_LONG;	}	if(c > 2) {		gopcode(OAS, f, Z, &t1);		f->xoffset += SZ_LONG;	}	if(c > 1) {		gopcode(OAS, &t2, Z, t);		t->xoffset += SZ_LONG;	}	if(c > 2) {		gopcode(OAS, &t1, Z, t);		t->xoffset += SZ_LONG;	}	regfree(&t1);	regfree(&t2);}

⌨️ 快捷键说明

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