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

📄 cgen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "gc.h"voidcgen(Node *n, Node *nn){	Node *l, *r;	Prog *p1;	Node nod, nod1, nod2, nod3, nod4;	int o;	long v, curs;	if(debug['g']) {		prtree(nn, "cgen lhs");		prtree(n, "cgen");	}	if(n == Z || n->type == T)		return;	if(typesuv[n->type->etype]) {		sugen(n, nn, n->type->width);		return;	}	l = n->left;	r = n->right;	o = n->op;	if(n->addable >= INDEXED) {		if(nn == Z) {			switch(o) {			default:				nullwarn(Z, Z);				break;			case OINDEX:				nullwarn(l, r);				break;			}			return;		}		gmove(n, nn);		return;	}	curs = cursafe;	if(n->complex >= FNX)	if(l->complex >= FNX)	if(r != Z && r->complex >= FNX)	switch(o) {	default:		regret(&nod, r);		cgen(r, &nod);		regsalloc(&nod1, r);		gopcode(OAS, &nod, Z, &nod1);		regfree(&nod);		nod = *n;		nod.right = &nod1;		cgen(&nod, nn);		return;	case OFUNC:	case OCOMMA:	case OANDAND:	case OOROR:	case OCOND:	case ODOT:		break;	}	switch(o) {	default:		diag(n, "unknown op in cgen: %O", o);		break;	case OAS:		if(l->op == OBIT)			goto bitas;		if(l->addable >= INDEXED) {			if(nn != Z || r->addable < INDEXED) {				if(r->complex >= FNX && nn == Z)					regret(&nod, r);				else					regalloc(&nod, r, nn);				cgen(r, &nod);				gmove(&nod, l);				if(nn != Z)					gmove(&nod, nn);				regfree(&nod);			} else				gmove(r, l);			break;		}		if(l->complex >= r->complex) {			reglcgen(&nod1, l, Z);			if(r->addable >= INDEXED) {				gmove(r, &nod1);				if(nn != Z)					gmove(r, nn);				regfree(&nod1);				break;			}			regalloc(&nod, r, nn);			cgen(r, &nod);		} else {			regalloc(&nod, r, nn);			cgen(r, &nod);			reglcgen(&nod1, l, Z);		}		gmove(&nod, &nod1);		regfree(&nod);		regfree(&nod1);		break;	bitas:		n = l->left;		regalloc(&nod, r, nn);		if(l->complex >= r->complex) {			reglcgen(&nod1, n, Z);			cgen(r, &nod);		} else {			cgen(r, &nod);			reglcgen(&nod1, n, Z);		}		regalloc(&nod2, n, Z);		gopcode(OAS, &nod1, Z, &nod2);		bitstore(l, &nod, &nod1, &nod2, nn);		break;	case OBIT:		if(nn == Z) {			nullwarn(l, Z);			break;		}		bitload(n, &nod, Z, Z, nn);		gopcode(OAS, &nod, Z, nn);		regfree(&nod);		break;	case OADD:	case OSUB:	case OAND:	case OOR:	case OXOR:	case OLSHR:	case OASHL:	case OASHR:		/*		 * immediate operands		 */		if(nn != Z)		if(r->op == OCONST)		if(!typefd[n->type->etype]) {			cgen(l, nn);			if(r->vconst == 0)			if(o != OAND)				break;			if(nn != Z)				gopcode(o, r, Z, nn);			break;		}	case OMUL:	case OLMUL:	case OLDIV:	case OLMOD:	case ODIV:	case OMOD:		if(nn == Z) {			nullwarn(l, r);			break;		}		if(o == OMUL || o == OLMUL) {			if(mulcon(n, nn))				break;			if(debug['M'])				print("%L multiply\n", n->lineno);		}		if(l->complex >= r->complex) {			regalloc(&nod, l, nn);			cgen(l, &nod);			regalloc(&nod1, r, Z);			cgen(r, &nod1);			gopcode(o, &nod1, Z, &nod);		} else {			regalloc(&nod, r, nn);			cgen(r, &nod);			regalloc(&nod1, l, Z);			cgen(l, &nod1);			gopcode(o, &nod, &nod1, &nod);		}		gopcode(OAS, &nod, Z, nn);		regfree(&nod);		regfree(&nod1);		break;	case OASLSHR:	case OASASHL:	case OASASHR:	case OASAND:	case OASADD:	case OASSUB:	case OASXOR:	case OASOR:		if(l->op == OBIT)			goto asbitop;		if(r->op == OCONST)		if(!typefd[n->type->etype]) {			if(l->addable < INDEXED)				reglcgen(&nod2, l, Z);			else				nod2 = *l;			regalloc(&nod, r, nn);			gopcode(OAS, &nod2, Z, &nod);			gopcode(o, r, Z, &nod);			gopcode(OAS, &nod, Z, &nod2);				regfree(&nod);			if(l->addable < INDEXED)				regfree(&nod2);			break;		}	case OASLMUL:	case OASLDIV:	case OASLMOD:	case OASMUL:	case OASDIV:	case OASMOD:		if(l->op == OBIT)			goto asbitop;		if(l->complex >= r->complex) {			if(l->addable < INDEXED)				reglcgen(&nod2, l, Z);			else				nod2 = *l;			regalloc(&nod, n, nn);			cgen(r, &nod);		} else {			regalloc(&nod, n, nn);			cgen(r, &nod);			if(l->addable < INDEXED)				reglcgen(&nod2, l, Z);			else				nod2 = *l;		}		regalloc(&nod1, n, Z);		gopcode(OAS, &nod2, Z, &nod1);		gopcode(o, &nod, &nod1, &nod);		gopcode(OAS, &nod, Z, &nod2);		regfree(&nod);		regfree(&nod1);		if(l->addable < INDEXED)			regfree(&nod2);		break;	asbitop:		regalloc(&nod4, n, nn);		regalloc(&nod3, r, Z);		if(l->complex >= r->complex) {			bitload(l, &nod, &nod1, &nod2, &nod4);			cgen(r, &nod3);		} else {			cgen(r, &nod3);			bitload(l, &nod, &nod1, &nod2, &nod4);		}		gmove(&nod, &nod4);		gopcode(n->op, &nod3, Z, &nod4);		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);			gopcode(OAS, &nod, Z, &nod1);			regfree(&nod);			nod = *n;			nod.left = &nod2;			nod2 = *l;			nod2.left = &nod1;			nod2.complex = 1;			cgen(&nod, nn);			return;		}		o = reg[REGARG];		gargs(r, &nod, &nod1);		if(l->addable < INDEXED) {			reglcgen(&nod, l, Z);			gopcode(OFUNC, Z, Z, &nod);			regfree(&nod);		} else			gopcode(OFUNC, Z, Z, l);		if(REGARG)			if(o != reg[REGARG])				reg[REGARG]--;		if(nn != Z) {			regret(&nod, n);			gopcode(OAS, &nod, Z, nn);			regfree(&nod);		}		break;	case OIND:		if(nn == Z) {			cgen(l, nn);			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);		gopcode(OAS, &nod, Z, 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;		}		regalloc(&nod, l, nn);		cgen(l, &nod);		regalloc(&nod1, n, &nod);		gopcode(OAS, &nod, Z, &nod1);		gopcode(OAS, &nod1, Z, nn);		regfree(&nod1);		regfree(&nod);		break;	case ODOT:		sugen(l, nodrat, l->type->width);		if(nn != Z) {			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(l->addable < INDEXED)			reglcgen(&nod2, l, Z);		else			nod2 = *l;		regalloc(&nod, l, nn);		gopcode(OAS, &nod2, Z, &nod);		regalloc(&nod1, l, Z);		if(typefd[l->type->etype]) {			regalloc(&nod3, l, Z);			if(v < 0) {				gopcode(OAS, nodfconst(-v), Z, &nod3);				gopcode(OSUB, &nod3, &nod, &nod1);			} else {				gopcode(OAS, nodfconst(v), Z, &nod3);				gopcode(OADD, &nod3, &nod, &nod1);			}			regfree(&nod3);		} else			gopcode(OADD, nodconst(v), &nod, &nod1);		gopcode(OAS, &nod1, Z, &nod2);		regfree(&nod);		regfree(&nod1);		if(l->addable < INDEXED)			regfree(&nod2);		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(l->addable < INDEXED)			reglcgen(&nod2, l, Z);		else			nod2 = *l;		regalloc(&nod, l, nn);		gopcode(OAS, &nod2, Z, &nod);		if(typefd[l->type->etype]) {			regalloc(&nod3, l, Z);			if(v < 0) {				gopcode(OAS, nodfconst(-v), Z, &nod3);				gopcode(OSUB, &nod3, Z, &nod);			} else {				gopcode(OAS, nodfconst(v), Z, &nod3);				gopcode(OADD, &nod3, Z, &nod);			}			regfree(&nod3);		} else			gopcode(OADD, nodconst(v), Z, &nod);		gopcode(OAS, &nod, Z, &nod2);		if(nn && l->op == ONAME)	/* in x=++i, emit USED(i) */			gins(ANOP, l, Z);		regfree(&nod);		if(l->addable < INDEXED)			regfree(&nod2);		break;	bitinc:		if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {			bitload(l, &nod, &nod1, &nod2, Z);			gopcode(OAS, &nod, Z, nn);			gopcode(OADD, nodconst(v), Z, &nod);			bitstore(l, &nod, &nod1, &nod2, Z);			break;		}		bitload(l, &nod, &nod1, &nod2, nn);		gopcode(OADD, nodconst(v), Z, &nod);		bitstore(l, &nod, &nod1, &nod2, nn);		break;	}	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);}void

⌨️ 快捷键说明

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