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

📄 cgen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
				case OASLMUL:					mulgen(n->type, r, &nod);					break;				case OASDIV:					sdiv2(r->vconst, v, l, &nod);					break;				case OASMOD:					smod2(r->vconst, v, l, &nod);					break;				}			havev:				gmove(&nod, &nod2);				if(nn != Z)					gmove(&nod, nn);				if(hardleft)					regfree(&nod2);				regfree(&nod);				goto done;			case OASLDIV:				c = r->vconst;				if((c & 0x80000000) == 0)					break;				if(hardleft)					reglcgen(&nod2, l, Z);				else					nod2 = *l;				regalloc(&nod1, l, nn);				cgen(&nod2, &nod1);				regalloc(&nod, l, nn);				zeroregm(&nod);				gins(ACMPL, &nod1, nodconst(c));				gins(ASBBL, nodconst(-1), &nod);				regfree(&nod1);				goto havev;			}		}		if(o == OASMUL) {/* should favour AX */			regalloc(&nod, l, nn);			if(r->complex >= FNX) {				regalloc(&nod1, r, Z);				cgen(r, &nod1);				r = &nod1;			}			if(hardleft)				reglcgen(&nod2, l, Z);			else				nod2 = *l;			cgen(&nod2, &nod);			if(r->addable < INDEXED) {				if(r->complex < FNX) {					regalloc(&nod1, r, Z);					cgen(r, &nod1);				}				gopcode(OASMUL, n->type, &nod1, &nod);				regfree(&nod1);			}			else				gopcode(OASMUL, n->type, r, &nod);			if(r == &nod1)				regfree(r);			gmove(&nod, &nod2);			if(nn != Z)				gmove(&nod, nn);			regfree(&nod);			if(hardleft)				regfree(&nod2);			goto done;		}		/*		 * get nod to be D_AX		 * get nod1 to be D_DX		 */		if(nodreg(&nod, nn, D_AX)) {			regsalloc(&nod2, n);			gmove(&nod, &nod2);			v = reg[D_AX];			reg[D_AX] = 0;			if(isreg(l, D_AX)) {				nod3 = *n;				nod3.left = &nod2;				cgen(&nod3, nn);			} else			if(isreg(r, D_AX)) {				nod3 = *n;				nod3.right = &nod2;				cgen(&nod3, nn);			} else				cgen(n, nn);			gmove(&nod2, &nod);			reg[D_AX] = v;			break;		}		if(nodreg(&nod1, nn, D_DX)) {			regsalloc(&nod2, n);			gmove(&nod1, &nod2);			v = reg[D_DX];			reg[D_DX] = 0;			if(isreg(l, D_DX)) {				nod3 = *n;				nod3.left = &nod2;				cgen(&nod3, nn);			} else			if(isreg(r, D_DX)) {				nod3 = *n;				nod3.right = &nod2;				cgen(&nod3, nn);			} else				cgen(n, nn);			gmove(&nod2, &nod1);			reg[D_DX] = v;			break;		}		reg[D_AX]++;		reg[D_DX]++;		if(l->complex >= r->complex) {			if(hardleft)				reglcgen(&nod2, l, Z);			else				nod2 = *l;			cgen(&nod2, &nod);			if(r->op == OCONST) {				switch(o) {				case OASDIV:					sdivgen(&nod2, r, &nod, &nod1);					goto divdone;				case OASLDIV:					udivgen(&nod2, r, &nod, &nod1);				divdone:					gmove(&nod1, &nod2);					if(nn != Z)						gmove(&nod1, nn);					goto freelxaxdx;				}			}			if(o == OASDIV || o == OASMOD)				gins(ACDQ, Z, Z);			if(o == OASLDIV || o == OASLMOD)				zeroregm(&nod1);			if(r->addable < INDEXED || r->op == OCONST ||			   !typeil[r->type->etype]) {				regalloc(&nod3, r, Z);				cgen(r, &nod3);				gopcode(o, l->type, &nod3, Z);				regfree(&nod3);			} else				gopcode(o, n->type, r, Z);		} else {			regalloc(&nod3, r, Z);			cgen(r, &nod3);			if(hardleft)				reglcgen(&nod2, l, Z);			else				nod2 = *l;			cgen(&nod2, &nod);			if(o == OASDIV || o == OASMOD)				gins(ACDQ, Z, Z);			if(o == OASLDIV || o == OASLMOD)				zeroregm(&nod1);			gopcode(o, l->type, &nod3, Z);			regfree(&nod3);		}		if(o == OASMOD || o == OASLMOD) {			gmove(&nod1, &nod2);			if(nn != Z)				gmove(&nod1, nn);		} else {			gmove(&nod, &nod2);			if(nn != Z)				gmove(&nod, nn);		}	freelxaxdx:		if(hardleft)			regfree(&nod2);		regfree(&nod);		regfree(&nod1);		break;	fop:		if(l->complex >= r->complex) {			cgen(l, &fregnode0);			if(r->addable < INDEXED) {				cgen(r, &fregnode0);				fgopcode(o, &fregnode0, &fregnode1, 1, 0);			} else				fgopcode(o, r, &fregnode0, 0, 0);		} else {			cgen(r, &fregnode0);			if(l->addable < INDEXED) {				cgen(l, &fregnode0);				fgopcode(o, &fregnode0, &fregnode1, 1, 1);			} else				fgopcode(o, l, &fregnode0, 0, 1);		}		gmove(&fregnode0, nn);		break;	asfop:		if(l->complex >= r->complex) {			if(hardleft)				reglcgen(&nod, l, Z);			else				nod = *l;			cgen(r, &fregnode0);		} else {			cgen(r, &fregnode0);			if(hardleft)				reglcgen(&nod, l, Z);			else				nod = *l;		}		if(!typefd[l->type->etype]) {			gmove(&nod, &fregnode0);			fgopcode(o, &fregnode0, &fregnode1, 1, 1);		} else			fgopcode(o, &nod, &fregnode0, 0, 1);		if(nn != Z)			gins(AFMOVD, &fregnode0, &fregnode0);		gmove(&fregnode0, &nod);		if(nn != Z)			gmove(&fregnode0, nn);		if(hardleft)			regfree(&nod);		break;	asbitop:		regalloc(&nod4, n, nn);		if(l->complex >= r->complex) {			bitload(l, &nod, &nod1, &nod2, &nod4);			regalloc(&nod3, r, Z);			cgen(r, &nod3);		} else {			regalloc(&nod3, r, Z);			cgen(r, &nod3);			bitload(l, &nod, &nod1, &nod2, &nod4);		}		gmove(&nod, &nod4);		if(typefd[nod3.type->etype])			fgopcode(o, &fregnode0, &fregnode1, 1, 1);		else {			Node onod;			/* incredible grot ... */			onod = nod3;			onod.op = o;			onod.complex = 2;			onod.addable = 0;			onod.type = tfield;			onod.left = &nod4;			onod.right = &nod3;			cgen(&onod, Z);		}		regfree(&nod3);		gmove(&nod4, &nod);		regfree(&nod4);		bitstore(l, &nod, &nod1, &nod2, nn);		break;	case OADDR:		if(nn == Z) {			nullwarn(l, Z);			break;		}		lcgen(l, nn);		break;	case OFUNC:		if(l->complex >= FNX) {			if(l->op != OIND)				diag(n, "bad function call");			regret(&nod, l->left);			cgen(l->left, &nod);			regsalloc(&nod1, l->left);			gmove(&nod, &nod1);			regfree(&nod);			nod = *n;			nod.left = &nod2;			nod2 = *l;			nod2.left = &nod1;			nod2.complex = 1;			cgen(&nod, nn);			return;		}		gargs(r, &nod, &nod1);		if(l->addable < INDEXED) {			reglcgen(&nod, l, nn);			nod.op = OREGISTER;			gopcode(OFUNC, n->type, Z, &nod);			regfree(&nod);		} else			gopcode(OFUNC, n->type, Z, l);		if(REGARG>=0 && reg[REGARG])			reg[REGARG]--;		if(nn != Z) {			regret(&nod, n);			gmove(&nod, nn);			regfree(&nod);		} else		if(typefd[n->type->etype])			gins(AFMOVDP, &fregnode0, &fregnode0);		break;	case OIND:		if(nn == Z) {			nullwarn(l, Z);			break;		}		regialloc(&nod, n, nn);		r = l;		while(r->op == OADD)			r = r->right;		if(sconst(r)) {			v = r->vconst;			r->vconst = 0;			cgen(l, &nod);			nod.xoffset += v;			r->vconst = v;		} else			cgen(l, &nod);		regind(&nod, n);		gmove(&nod, nn);		regfree(&nod);		break;	case OEQ:	case ONE:	case OLE:	case OLT:	case OGE:	case OGT:	case OLO:	case OLS:	case OHI:	case OHS:		if(nn == Z) {			nullwarn(l, r);			break;		}		boolgen(n, 1, nn);		break;	case OANDAND:	case OOROR:		boolgen(n, 1, nn);		if(nn == Z)			patch(p, pc);		break;	case ONOT:		if(nn == Z) {			nullwarn(l, Z);			break;		}		boolgen(n, 1, nn);		break;	case OCOMMA:		cgen(l, Z);		cgen(r, nn);		break;	case OCAST:		if(nn == Z) {			nullwarn(l, Z);			break;		}		/*		 * convert from types l->n->nn		 */		if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {			/* both null, gen l->nn */			cgen(l, nn);			break;		}		if(typev[l->type->etype]) {			cgen64(n, nn);			break;		}		regalloc(&nod, l, nn);		cgen(l, &nod);		regalloc(&nod1, n, &nod);		gmove(&nod, &nod1);		gmove(&nod1, nn);		regfree(&nod1);		regfree(&nod);		break;	case ODOT:		sugen(l, nodrat, l->type->width);		if(nn == Z)			break;		warn(n, "non-interruptable temporary");		nod = *nodrat;		if(!r || r->op != OCONST) {			diag(n, "DOT and no offset");			break;		}		nod.xoffset += (long)r->vconst;		nod.type = n->type;		cgen(&nod, nn);		break;	case OCOND:		bcgen(l, 1);		p1 = p;		cgen(r->left, nn);		gbranch(OGOTO);		patch(p1, pc);		p1 = p;		cgen(r->right, nn);		patch(p1, pc);		break;	case OPOSTINC:	case OPOSTDEC:		v = 1;		if(l->type->etype == TIND)			v = l->type->link->width;		if(o == OPOSTDEC)			v = -v;		if(l->op == OBIT)			goto bitinc;		if(nn == Z)			goto pre;		if(hardleft)			reglcgen(&nod, l, Z);		else			nod = *l;		if(typefd[n->type->etype])			goto fltinc;		gmove(&nod, nn);		gopcode(OADD, n->type, nodconst(v), &nod);		if(hardleft)			regfree(&nod);		break;	case OPREINC:	case OPREDEC:		v = 1;		if(l->type->etype == TIND)			v = l->type->link->width;		if(o == OPREDEC)			v = -v;		if(l->op == OBIT)			goto bitinc;	pre:		if(hardleft)			reglcgen(&nod, l, Z);		else			nod = *l;		if(typefd[n->type->etype])			goto fltinc;		gopcode(OADD, n->type, nodconst(v), &nod);		if(nn != Z)			gmove(&nod, nn);		if(hardleft)			regfree(&nod);		break;	fltinc:		gmove(&nod, &fregnode0);		if(nn != Z && (o == OPOSTINC || o == OPOSTDEC))			gins(AFMOVD, &fregnode0, &fregnode0);		gins(AFLD1, Z, Z);		if(v < 0)			fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0);		else			fgopcode(OADD, &fregnode0, &fregnode1, 1, 0);		if(nn != Z && (o == OPREINC || o == OPREDEC))			gins(AFMOVD, &fregnode0, &fregnode0);		gmove(&fregnode0, &nod);		if(hardleft)			regfree(&nod);		break;	bitinc:		if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {			bitload(l, &nod, &nod1, &nod2, Z);			gmove(&nod, nn);			gopcode(OADD, tfield, nodconst(v), &nod);			bitstore(l, &nod, &nod1, &nod2, Z);			break;		}		bitload(l, &nod, &nod1, &nod2, nn);		gopcode(OADD, tfield, nodconst(v), &nod);		bitstore(l, &nod, &nod1, &nod2, nn);		break;	}done:	cursafe = curs;}voidreglcgen(Node *t, Node *n, Node *nn){	Node *r;	long v;	regialloc(t, n, nn);	if(n->op == OIND) {		r = n->left;		while(r->op == OADD)			r = r->right;		if(sconst(r)) {			v = r->vconst;			r->vconst = 0;			lcgen(n, t);			t->xoffset += v;			r->vconst = v;			regind(t, n);			return;		}	}	lcgen(n, t);	regind(t, n);}voidlcgen(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;		}		gopcode(OADDR, n->type, n, 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(typev[n->type->etype]) {			testv(n, true);			goto com;		}		o = ONE;		if(true)			o = OEQ;		if(typefd[n->type->etype]) {

⌨️ 快捷键说明

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