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

📄 cgen.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "gc.h"/* ,x/^(print|prtree)\(/i/\/\/ */voidcgen(Node *n, Node *nn){	Node *l, *r, *t;	Prog *p1;	Node nod, nod1, nod2, nod3, nod4;	int o, hardleft;	long v, curs;	vlong c;	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(l->complex >= FNX)	if(r != Z && r->complex >= FNX)	switch(o) {	default:		if(cond(o) && typesuv[l->type->etype])			break;		regret(&nod, r);		cgen(r, &nod);		regsalloc(&nod1, r);		gmove(&nod, &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;	}	hardleft = l->addable < INDEXED || l->complex >= FNX;	switch(o) {	default:		diag(n, "unknown op in cgen: %O", o);		break;	case ONEG:	case OCOM:		if(nn == Z) {			nullwarn(l, Z);			break;		}		regalloc(&nod, l, nn);		cgen(l, &nod);		gopcode(o, n->type, Z, &nod);		gmove(&nod, nn);		regfree(&nod);		break;	case OAS:		if(typefd[n->type->etype]) {			cgen(r, &fregnode0);			if(nn != Z)				gins(AFMOVD, &fregnode0, &fregnode0);			if(l->addable < INDEXED) {				reglcgen(&nod, l, Z);				gmove(&fregnode0, &nod);				regfree(&nod);			} else				gmove(&fregnode0, l);			if(nn != Z)				gmove(&fregnode0, nn);			return;		}		if(l->op == OBIT)			goto bitas;		if(!hardleft) {			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) {			if(l->op == OINDEX && r->op == OCONST) {				gmove(r, l);				break;			}			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);		gmove(&nod1, &nod2);		bitstore(l, &nod, &nod1, &nod2, nn);		break;	case OBIT:		if(nn == Z) {			nullwarn(l, Z);			break;		}		bitload(n, &nod, Z, Z, nn);		gmove(&nod, nn);		regfree(&nod);		break;	case OLSHR:	case OASHL:	case OASHR:		if(nn == Z) {			nullwarn(l, r);			break;		}		if(r->op == OCONST) {			if(r->vconst == 0) {				cgen(l, nn);				break;			}			regalloc(&nod, l, nn);			cgen(l, &nod);			if(o == OASHL && r->vconst == 1)				gopcode(OADD, n->type, &nod, &nod);			else				gopcode(o, n->type, r, &nod);			gmove(&nod, nn);			regfree(&nod);			break;		}		/*		 * get nod to be D_CX		 */		if(nodreg(&nod, nn, D_CX)) {			regsalloc(&nod1, n);			gmove(&nod, &nod1);			cgen(n, &nod);		/* probably a bug */			gmove(&nod, nn);			gmove(&nod1, &nod);			break;		}		reg[D_CX]++;		if(nn->op == OREGISTER && nn->reg == D_CX)			regalloc(&nod1, l, Z);		else			regalloc(&nod1, l, nn);		if(r->complex >= l->complex) {			cgen(r, &nod);			cgen(l, &nod1);		} else {			cgen(l, &nod1);			cgen(r, &nod);		}		gopcode(o, n->type, &nod, &nod1);		gmove(&nod1, nn);		regfree(&nod);		regfree(&nod1);		break;	case OADD:	case OSUB:	case OOR:	case OXOR:	case OAND:		if(nn == Z) {			nullwarn(l, r);			break;		}		if(typefd[n->type->etype])			goto fop;		if(r->op == OCONST) {			if(r->vconst == 0 && o != OAND) {				cgen(l, nn);				break;			}		}		if(n->op == OADD && l->op == OASHL && l->right->op == OCONST		&& (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {			c = l->right->vconst;			if(c > 0 && c <= 3) {				if(l->left->complex >= r->complex) {					regalloc(&nod, l->left, nn);					cgen(l->left, &nod);					if(r->addable < INDEXED) {						regalloc(&nod1, r, Z);						cgen(r, &nod1);						genmuladd(&nod, &nod, 1 << c, &nod1);						regfree(&nod1);					}					else						genmuladd(&nod, &nod, 1 << c, r);				}				else {					regalloc(&nod, r, nn);					cgen(r, &nod);					regalloc(&nod1, l->left, Z);					cgen(l->left, &nod1);					genmuladd(&nod, &nod1, 1 << c, &nod);					regfree(&nod1);				}				gmove(&nod, nn);				regfree(&nod);				break;			}		}		if(r->addable >= INDEXED) {			regalloc(&nod, l, nn);			cgen(l, &nod);			gopcode(o, n->type, r, &nod);			gmove(&nod, nn);			regfree(&nod);			break;		}		if(l->complex >= r->complex) {			regalloc(&nod, l, nn);			cgen(l, &nod);			regalloc(&nod1, r, Z);			cgen(r, &nod1);			gopcode(o, n->type, &nod1, &nod);		} else {			regalloc(&nod1, r, nn);			cgen(r, &nod1);			regalloc(&nod, l, Z);			cgen(l, &nod);			gopcode(o, n->type, &nod1, &nod);		}		gmove(&nod, nn);		regfree(&nod);		regfree(&nod1);		break;	case OLMOD:	case OMOD:	case OLMUL:	case OLDIV:	case OMUL:	case ODIV:		if(nn == Z) {			nullwarn(l, r);			break;		}		if(typefd[n->type->etype])			goto fop;		if(r->op == OCONST) {			SET(v);			switch(o) {			case ODIV:			case OMOD:				c = r->vconst;				if(c < 0)					c = -c;				v = log2(c);				if(v < 0)					break;				/* fall thru */			case OMUL:			case OLMUL:				regalloc(&nod, l, nn);				cgen(l, &nod);				switch(o) {				case OMUL:				case OLMUL:					mulgen(n->type, r, &nod);					break;				case ODIV:					sdiv2(r->vconst, v, l, &nod);					break;				case OMOD:					smod2(r->vconst, v, l, &nod);					break;				}				gmove(&nod, nn);				regfree(&nod);				goto done;			case OLDIV:				c = r->vconst;				if((c & 0x80000000) == 0)					break;				regalloc(&nod1, l, Z);				cgen(l, &nod1);				regalloc(&nod, l, nn);				zeroregm(&nod);				gins(ACMPL, &nod1, nodconst(c));				gins(ASBBL, nodconst(-1), &nod);				regfree(&nod1);				gmove(&nod, nn);				regfree(&nod);				goto done;			}		}		if(o == OMUL) {			if(l->addable >= INDEXED) {				t = l;				l = r;				r = t;				goto imula;			}			else if(r->addable >= INDEXED) {			imula:/* should favour AX */				regalloc(&nod, l, nn);				cgen(l, &nod);				gopcode(OMUL, n->type, r, &nod);			}			else {/* should favour AX */				regalloc(&nod, l, nn);				cgen(l, &nod);				regalloc(&nod1, r, Z);				cgen(r, &nod1);				gopcode(OMUL, n->type, &nod1, &nod);				regfree(&nod1);			}			gmove(&nod, nn);			regfree(&nod);			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]++;		if(r->op == OCONST) {			switch(o) {			case ODIV:				reg[D_DX]++;				if(l->addable < INDEXED) {					regalloc(&nod2, l, Z);					cgen(l, &nod2);					l = &nod2;				}				sdivgen(l, r, &nod, &nod1);				gmove(&nod1, nn);				if(l == &nod2)					regfree(l);				goto freeaxdx;			case OLDIV:				reg[D_DX]++;				if(l->addable < INDEXED) {					regalloc(&nod2, l, Z);					cgen(l, &nod2);					l = &nod2;				}				udivgen(l, r, &nod, &nod1);				gmove(&nod1, nn);				if(l == &nod2)					regfree(l);				goto freeaxdx;			}		}		if(l->complex >= r->complex) {			cgen(l, &nod);			reg[D_DX]++;			if(o == ODIV || o == OMOD)				gins(ACDQ, Z, Z);			if(o == OLDIV || o == OLMOD)				zeroregm(&nod1);			if(r->addable < INDEXED || r->op == OCONST) {				regsalloc(&nod3, r);				cgen(r, &nod3);				gopcode(o, n->type, &nod3, Z);			} else				gopcode(o, n->type, r, Z);		} else {			regsalloc(&nod3, r);			cgen(r, &nod3);			cgen(l, &nod);			reg[D_DX]++;			if(o == ODIV || o == OMOD)				gins(ACDQ, Z, Z);			if(o == OLDIV || o == OLMOD)				zeroregm(&nod1);			gopcode(o, n->type, &nod3, Z);		}		if(o == OMOD || o == OLMOD)			gmove(&nod1, nn);		else			gmove(&nod, nn);	freeaxdx:		regfree(&nod);		regfree(&nod1);		break;	case OASLSHR:	case OASASHL:	case OASASHR:		if(r->op == OCONST)			goto asand;		if(l->op == OBIT)			goto asbitop;		if(typefd[n->type->etype])			goto asfop;		/*		 * get nod to be D_CX		 */		if(nodreg(&nod, nn, D_CX)) {			regsalloc(&nod1, n);			gmove(&nod, &nod1);			cgen(n, &nod);			if(nn != Z)				gmove(&nod, nn);			gmove(&nod1, &nod);			break;		}		reg[D_CX]++;		if(r->complex >= l->complex) {			cgen(r, &nod);			if(hardleft)				reglcgen(&nod1, l, Z);			else				nod1 = *l;		} else {			if(hardleft)				reglcgen(&nod1, l, Z);			else				nod1 = *l;			cgen(r, &nod);		}		gopcode(o, l->type, &nod, &nod1);		regfree(&nod);		if(nn != Z)			gmove(&nod1, nn);		if(hardleft)			regfree(&nod1);		break;	case OASAND:	case OASADD:	case OASSUB:	case OASXOR:	case OASOR:	asand:		if(l->op == OBIT)			goto asbitop;		if(typefd[n->type->etype]||typefd[r->type->etype])			goto asfop;		if(l->complex >= r->complex) {			if(hardleft)				reglcgen(&nod, l, Z);			else				nod = *l;			if(r->op != OCONST) {				regalloc(&nod1, r, nn);				cgen(r, &nod1);				gopcode(o, l->type, &nod1, &nod);				regfree(&nod1);			} else				gopcode(o, l->type, r, &nod);		} else {			regalloc(&nod1, r, nn);			cgen(r, &nod1);			if(hardleft)				reglcgen(&nod, l, Z);			else				nod = *l;			gopcode(o, l->type, &nod1, &nod);			regfree(&nod1);		}		if(nn != Z)			gmove(&nod, nn);		if(hardleft)			regfree(&nod);		break;	case OASLMUL:	case OASLDIV:	case OASLMOD:	case OASMUL:	case OASDIV:	case OASMOD:		if(l->op == OBIT)			goto asbitop;		if(typefd[n->type->etype]||typefd[r->type->etype])			goto asfop;		if(r->op == OCONST) {			SET(v);			switch(o) {			case OASDIV:			case OASMOD:				c = r->vconst;				if(c < 0)					c = -c;				v = log2(c);				if(v < 0)					break;				/* fall thru */			case OASMUL:			case OASLMUL:				if(hardleft)					reglcgen(&nod2, l, Z);				else					nod2 = *l;				regalloc(&nod, l, nn);				cgen(&nod2, &nod);				switch(o) {				case OASMUL:

⌨️ 快捷键说明

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