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

📄 cgen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
			if(n->addable < INDEXED) {				cgen(n, &fregnode0);				gins(AFLDZ, Z, Z);				fgopcode(o, &fregnode0, &fregnode1, 1, 1);			} else {				gins(AFLDZ, Z, Z);				fgopcode(o, n, &fregnode0, 0, 1);			}			goto com;		}		/* bad, 13 is address of external that becomes constant */		if(n->addable >= INDEXED && n->addable != 13) {			gopcode(o, n->type, n, nodconst(0));			goto com;		}		regalloc(&nod, n, nn);		cgen(n, &nod);		gopcode(o, n->type, &nod, nodconst(0));		regfree(&nod);		goto com;	case OCONST:		o = vconst(n);		if(!true)			o = !o;		gbranch(OGOTO);		if(o) {			p1 = p;			gbranch(OGOTO);			patch(p1, pc);		}		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(typev[l->type->etype]) {			if(!true)				n->op = comrel[relindex(o)];			cgen64(n, Z);			goto com;		}		if(true)			o = comrel[relindex(o)];		if(l->complex >= FNX && r->complex >= FNX) {			regret(&nod, r);			cgen(r, &nod);			regsalloc(&nod1, r);			gmove(&nod, &nod1);			regfree(&nod);			nod = *n;			nod.right = &nod1;			boolgen(&nod, true, nn);			break;		}		if(typefd[l->type->etype]) {			if(l->complex >= r->complex) {				cgen(l, &fregnode0);				if(r->addable < INDEXED) {					cgen(r, &fregnode0);					o = invrel[relindex(o)];					fgopcode(o, &fregnode0, &fregnode1, 1, 1);				} else					fgopcode(o, r, &fregnode0, 0, 1);			} else {				o = invrel[relindex(o)];				cgen(r, &fregnode0);				if(l->addable < INDEXED) {					cgen(l, &fregnode0);					o = invrel[relindex(o)];					fgopcode(o, &fregnode0, &fregnode1, 1, 1);				} else					fgopcode(o, l, &fregnode0, 0, 1);			}			goto com;		}		if(l->op == OCONST) {			o = invrel[relindex(o)];			/* bad, 13 is address of external that becomes constant */			if(r->addable < INDEXED || r->addable == 13) {				regalloc(&nod, r, nn);				cgen(r, &nod);				gopcode(o, l->type, &nod, l);				regfree(&nod);			} else				gopcode(o, l->type, r, l);			goto com;		}		if(l->complex >= r->complex) {			regalloc(&nod, l, nn);			cgen(l, &nod);			if(r->addable < INDEXED) {				regalloc(&nod1, r, Z);				cgen(r, &nod1);				gopcode(o, l->type, &nod, &nod1);				regfree(&nod1);			} else				gopcode(o, l->type, &nod, r);			regfree(&nod);			goto com;		}		regalloc(&nod, r, nn);		cgen(r, &nod);		if(l->addable < INDEXED || l->addable == 13) {			regalloc(&nod1, l, Z);			cgen(l, &nod1);			if(typechlp[l->type->etype])				gopcode(o, types[TINT], &nod1, &nod);			else				gopcode(o, l->type, &nod1, &nod);			regfree(&nod1);		} else			gopcode(o, l->type, l, &nod);		regfree(&nod);	com:		if(nn != Z) {			p1 = p;			gmove(nodconst(1L), nn);			gbranch(OGOTO);			p2 = p;			patch(p1, pc);			gmove(nodconst(0L), nn);			patch(p2, pc);		}		break;	}	cursafe = curs;}voidsugen(Node *n, Node *nn, long w){	Prog *p1;	Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r;	Type *t;	int c, v, x;	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;			}			if(nn->op == OREGPAIR) {				loadpair(n, nn);				break;			}			else if(!vaddr(nn, 0)) {				t = nn->type;				nn->type = types[TLONG];				reglcgen(&nod1, nn, Z);				nn->type = t;				gmove(lo64(n), &nod1);				nod1.xoffset += SZ_LONG;				gmove(hi64(n), &nod1);				regfree(&nod1);			}			else {				gins(AMOVL, lo64(n), nn);				nn->xoffset += SZ_LONG;				gins(AMOVL, hi64(n), nn);				nn->xoffset -= SZ_LONG;				break;			}			break;		}		goto copy;	case ODOT:		l = n->left;		sugen(l, nodrat, l->type->width);		if(nn == Z)			break;		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 && side(nn)) {			nod1 = *n;			nod1.type = typ(TIND, n->type);			regret(&nod2, &nod1);			lcgen(nn, &nod2);			regsalloc(&nod0, &nod1);			cgen(&nod2, &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 = nil;			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;			nod0.right = l;			/* prtree(&nod0, "hand craft"); /* */			cgen(&nod0, Z);		}		break;	case OAS:		if(nn == Z) {			if(n->addable < INDEXED)				sugen(n->right, n->left, w);			break;		}		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;		}		h = nn;		if(nn->op == OREGPAIR) {			regsalloc(&nod1, nn);			nn = &nod1;		}		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);		if(h->op == OREGPAIR)			loadpair(nn->left, h);		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) {		switch(n->op) {		case OASADD:		case OASSUB:		case OASAND:		case OASOR:		case OASXOR:		case OASMUL:		case OASLMUL:		case OASASHL:		case OASASHR:		case OASLSHR:			break;		case OPOSTINC:		case OPOSTDEC:		case OPREINC:		case OPREDEC:			break;		default:			return;		}	}	if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {		t = nn->type;		nn->type = types[TLONG];		regialloc(&nod1, nn, Z);		lcgen(nn, &nod1);		regsalloc(&nod2, nn);		nn->type = t;		gins(AMOVL, &nod1, &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;	}	x = 0;	v = w == 8;	if(v) {		c = cursafe;		if(n->left != Z && n->left->complex >= FNX		&& n->right != Z && n->right->complex >= FNX) {//			warn(n, "toughie");			regsalloc(&nod1, n->right);			cgen(n->right, &nod1);			nod2 = *n;			nod2.right = &nod1;			cgen(&nod2, nn);			cursafe = c;			return;		}		if(cgen64(n, nn)) {			cursafe = c;			return;		}		if(n->op == OCOM) {			n = n->left;			x = 1;		}	}	/* botch, need to save in .safe */	c = 0;	if(n->complex > nn->complex) {		t = n->type;		n->type = types[TLONG];		if(v) {			regalloc(&nod0, n, Z);			if(!vaddr(n, 0)) {				reglcgen(&nod1, n, Z);				n->type = t;				n = &nod1;			}			else				n->type = t;		}		else {			nodreg(&nod1, n, D_SI);			if(reg[D_SI]) {				gins(APUSHL, &nod1, Z);				c |= 1;				reg[D_SI]++;			}			lcgen(n, &nod1);			n->type = t;		}		t = nn->type;		nn->type = types[TLONG];		if(v) {			if(!vaddr(nn, 0)) {				reglcgen(&nod2, nn, Z);				nn->type = t;				nn = &nod2;			}			else				nn->type = t;		}		else {			nodreg(&nod2, nn, D_DI);			if(reg[D_DI]) {				gins(APUSHL, &nod2, Z);				c |= 2;				reg[D_DI]++;			}			lcgen(nn, &nod2);			nn->type = t;		}	} else {		t = nn->type;		nn->type = types[TLONG];		if(v) {			regalloc(&nod0, nn, Z);			if(!vaddr(nn, 0)) {				reglcgen(&nod2, nn, Z);				nn->type = t;				nn = &nod2;			}			else				nn->type = t;		}		else {			nodreg(&nod2, nn, D_DI);			if(reg[D_DI]) {				gins(APUSHL, &nod2, Z);				c |= 2;				reg[D_DI]++;			}			lcgen(nn, &nod2);			nn->type = t;		}		t = n->type;		n->type = types[TLONG];		if(v) {			if(!vaddr(n, 0)) {				reglcgen(&nod1, n, Z);				n->type = t;				n = &nod1;			}			else				n->type = t;		}		else {			nodreg(&nod1, n, D_SI);			if(reg[D_SI]) {				gins(APUSHL, &nod1, Z);				c |= 1;				reg[D_SI]++;			}			lcgen(n, &nod1);			n->type = t;		}	}	if(v) {		gins(AMOVL, n, &nod0);		if(x)			gins(ANOTL, Z, &nod0);		gins(AMOVL, &nod0, nn);		n->xoffset += SZ_LONG;		nn->xoffset += SZ_LONG;		gins(AMOVL, n, &nod0);		if(x)			gins(ANOTL, Z, &nod0);		gins(AMOVL, &nod0, nn);		n->xoffset -= SZ_LONG;		nn->xoffset -= SZ_LONG;		if(nn == &nod2)			regfree(&nod2);		if(n == &nod1)			regfree(&nod1);		regfree(&nod0);		return;	}	nodreg(&nod3, n, D_CX);	if(reg[D_CX]) {		gins(APUSHL, &nod3, Z);		c |= 4;		reg[D_CX]++;	}	gins(AMOVL, nodconst(w/SZ_LONG), &nod3);	gins(ACLD, Z, Z);	gins(AREP, Z, Z);	gins(AMOVSL, Z, Z);	if(c & 4) {		gins(APOPL, Z, &nod3);		reg[D_CX]--;	}	if(c & 2) {		gins(APOPL, Z, &nod2);		reg[nod2.reg]--;	}	if(c & 1) {		gins(APOPL, Z, &nod1);		reg[nod1.reg]--;	}}

⌨️ 快捷键说明

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