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

📄 cgen64.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
				l = t;			}			break;		case IMM(0, 1):			if(dr)				t = nn;			else				t = regpair(Z, n);			sugen(l, t, 8);			l = t;			break;		case IMM(1, 0):			if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {				lri = IMM(0, 0);				goto bin00;			}			if(dr)				t = nn;			else				t = regpair(Z, n);			sugen(r, t, 8);			r = t;			break;		case IMM(1, 1):			break;		}#define	WW(l, r)	((l) | ((r) << 2))		d = Z;		dt = nn->type;		nn->type = types[TLONG];		switch(lri) {		case IMM(0, 0):			biggen(l, r, Z, 0, binop00, args);			break;		case IMM(0, 1):			switch(ri) {			case WNONE:				diag(r, "bad whatof\n");				break;			case WCONST:				biggen(l, r, Z, 0, optab[B0c], args);				break;			case WHARD:				reglcgen(&nod2, r, Z);				r = &nod2;				/* fall thru */			case WADDR:				biggen(l, r, Z, 0, binoptmp, args);				if(ri == WHARD)					regfree(r);				break;			}			break;		case IMM(1, 0):			if(n->op == OSUB) {				switch(li) {				case WNONE:					diag(l, "bad whatof\n");					break;				case WHARD:					reglcgen(&nod2, l, Z);					l = &nod2;					/* fall thru */				case WADDR:				case WCONST:					biggen(l, r, Z, 0, sub10, args);					break;				}				if(li == WHARD)					regfree(l);			}			else {				switch(li) {				case WNONE:					diag(l, "bad whatof\n");					break;				case WCONST:					biggen(r, l, Z, 0, optab[B0c], args);					break;				case WHARD:					reglcgen(&nod2, l, Z);					l = &nod2;					/* fall thru */				case WADDR:					biggen(r, l, Z, 0, binoptmp, args);					if(li == WHARD)						regfree(l);					break;				}			}			break;		case IMM(1, 1):			switch(WW(li, ri)) {			case WW(WCONST, WHARD):				if(r->op == ONAME && n->op == OAND && reduxv(l))					ri = WADDR;				break;			case WW(WHARD, WCONST):				if(l->op == ONAME && n->op == OAND && reduxv(r))					li = WADDR;				break;			}			if(li == WHARD) {				reglcgen(&nod3, l, Z);				l = &nod3;			}			if(ri == WHARD) {				reglcgen(&nod2, r, Z);				r = &nod2;			}			d = regpair(nn, n);			instpair(d, Z);			switch(WW(li, ri)) {			case WW(WCONST, WADDR):			case WW(WCONST, WHARD):				biggen(l, r, d, 0, optab[Bca], args);				break;			case WW(WADDR, WCONST):			case WW(WHARD, WCONST):				biggen(l, r, d, 0, optab[Bac], args);				break;			case WW(WADDR, WADDR):			case WW(WADDR, WHARD):			case WW(WHARD, WADDR):			case WW(WHARD, WHARD):				biggen(l, r, d, 0, binop11, args);				break;			default:				diag(r, "bad whatof pair %d %d\n", li, ri);				break;			}			if(li == WHARD)				regfree(l);			if(ri == WHARD)				regfree(r);			break;		}		nn->type = dt;		if(d != Z)			goto finished;		switch(lri) {		case IMM(0, 0):			freepair(r);			/* fall thru */;		case IMM(0, 1):			if(!dr)				storepair(l, nn, 1);			break;		case IMM(1, 0):			if(!dr)				storepair(r, nn, 1);			break;		case IMM(1, 1):			break;		}		return 1;	shift:		c = Z;		/* evaluate hard subexps, stealing nn if possible. */		/* must also secure CX.  not as many optims as binop. */		switch(lri) {		case IMM(0, 0):		imm00:			if(l->complex + 1 > r->complex) {				if(dr)					t = nn;				else					t = regpair(Z, l);				sugen(l, t, 8);				l = t;				t = &nod1;				c = snarfreg(l, t, D_CX, r, &nod2);				cgen(r, t);				r = t;			}			else {				t = &nod1;				c = snarfreg(nn, t, D_CX, r, &nod2);				cgen(r, t);				r = t;				if(dr)					t = nn;				else					t = regpair(Z, l);				sugen(l, t, 8);				l = t;			}			break;		case IMM(0, 1):		imm01:			if(ri != WCONST) {				lri = IMM(0, 0);				goto imm00;			}			if(dr)				t = nn;			else				t = regpair(Z, n);			sugen(l, t, 8);			l = t;			break;		case IMM(1, 0):		imm10:			if(li != WCONST) {				lri = IMM(0, 0);				goto imm00;			}			t = &nod1;			c = snarfreg(nn, t, D_CX, r, &nod2);			cgen(r, t);			r = t;			break;		case IMM(1, 1):			if(ri != WCONST) {				lri = IMM(1, 0);				goto imm10;			}			if(li == WHARD) {				lri = IMM(0, 1);				goto imm01;			}			break;		}		d = Z;		switch(lri) {		case IMM(0, 0):			biggen(l, r, Z, 0, optab[S00], args);			break;		case IMM(0, 1):			switch(ri) {			case WNONE:			case WADDR:			case WHARD:				diag(r, "bad whatof\n");				break;			case WCONST:				m = r->vconst & 63;				s = nodconst(m);				if(m < 32)					cp = optab[Sc0];				else if(m == 32)					cp = optab[Sc1];				else					cp = optab[Sc2];				biggen(l, s, Z, 0, cp, args);				break;			}			break;		case IMM(1, 0):			/* left is const */			d = regpair(nn, n);			instpair(d, Z);			biggen(l, r, d, 0, optab[S10], args);			regfree(r);			break;		case IMM(1, 1):			d = regpair(nn, n);			instpair(d, Z);			switch(WW(li, ri)) {			case WW(WADDR, WCONST):				m = r->vconst & 63;				s = nodconst(m);				if(m < 32) {					loadpair(l, d);					l = d;					cp = optab[Sc0];				}				else if(m == 32)					cp = optab[Sac3];				else					cp = optab[Sac4];				biggen(l, s, d, 0, cp, args);				break;			default:				diag(r, "bad whatof pair %d %d\n", li, ri);				break;			}			break;		}		if(c != Z) {			gins(AMOVL, c, r);			regfree(c);		}		if(d != Z)			goto finished;		switch(lri) {		case IMM(0, 0):			regfree(r);			/* fall thru */		case IMM(0, 1):			if(!dr)				storepair(l, nn, 1);			break;		case IMM(1, 0):			regfree(r);			break;		case IMM(1, 1):			break;		}		return 1;	cmp:		op = n->op;		/* evaluate hard subexps */		switch(lri) {		case IMM(0, 0):			if(l->complex > r->complex) {				t = regpair(Z, l);				sugen(l, t, 8);				l = t;				t = regpair(Z, r);				sugen(r, t, 8);				r = t;			}			else {				t = regpair(Z, r);				sugen(r, t, 8);				r = t;				t = regpair(Z, l);				sugen(l, t, 8);				l = t;			}			break;		case IMM(1, 0):			t = r;			r = l;			l = t;			ri = li;			op = invrel[relindex(op)];			/* fall thru */		case IMM(0, 1):			t = regpair(Z, l);			sugen(l, t, 8);			l = t;			break;		case IMM(1, 1):			break;		}		true = 1;		optab = cmptab;		switch(op) {		case OEQ:			optab = NEtab;			true = 0;			break;		case ONE:			optab = NEtab;			break;		case OLE:			args = GTargs;			true = 0;			break;		case OGT:			args = GTargs;			break;		case OLS:			args = HIargs;			true = 0;			break;		case OHI:			args = HIargs;			break;		case OLT:			args = GEargs;			true = 0;			break;		case OGE:			args = GEargs;			break;		case OLO:			args = HSargs;			true = 0;			break;		case OHS:			args = HSargs;			break;		default:			diag(n, "bad cmp\n");			SET(optab);		}		switch(lri) {		case IMM(0, 0):			biggen(l, r, Z, true, optab[T0i], args);			break;		case IMM(0, 1):		case IMM(1, 0):			switch(ri) {			case WNONE:				diag(l, "bad whatof\n");				break;			case WCONST:				biggen(l, r, Z, true, optab[T0i], args);				break;			case WHARD:				reglcgen(&nod2, r, Z);				r = &nod2;				/* fall thru */			case WADDR:				biggen(l, r, Z, true, optab[T0i], args);				if(ri == WHARD)					regfree(r);				break;			}			break;		case IMM(1, 1):			if(li == WHARD) {				reglcgen(&nod3, l, Z);				l = &nod3;			}			if(ri == WHARD) {				reglcgen(&nod2, r, Z);				r = &nod2;			}			biggen(l, r, Z, true, optab[Tii], args);			if(li == WHARD)				regfree(l);			if(ri == WHARD)				regfree(r);			break;		}		switch(lri) {		case IMM(0, 0):			freepair(r);			/* fall thru */;		case IMM(0, 1):		case IMM(1, 0):			freepair(l);			break;		case IMM(1, 1):			break;		}		return 1;	case OASMUL:	case OASLMUL:		m = 0;		goto mulop;	case OMUL:	case OLMUL:		m = 1;		goto mulop;	mulop:		dr = nn != Z && nn->op == OREGPAIR;		l = vfunc(n->left, nn);		r = vfunc(n->right, nn);		if(r->op != OCONST) {			if(l->complex > r->complex) {				if(m) {					t = l;					l = r;					r = t;				}				else if(!vaddr(l, 1)) {					reglcgen(&nod5, l, Z);					l = &nod5;					evacaxdx(l);				}			}			t = regpair(Z, n);			sugen(r, t, 8);			r = t;			evacaxdx(r->left);			evacaxdx(r->right);			if(l->complex <= r->complex && !m && !vaddr(l, 1)) {				reglcgen(&nod5, l, Z);				l = &nod5;				evacaxdx(l);			}		}		if(dr)			t = nn;		else			t = regpair(Z, n);		c = Z;		d = Z;		if(!nodreg(&nod1, t->left, D_AX)) {			if(t->left->reg != D_AX){				t->left->reg = D_AX;				reg[D_AX]++;			}else if(reg[D_AX] == 0)				fatal(Z, "vlong mul AX botch");		}		if(!nodreg(&nod2, t->right, D_DX)) {			if(t->right->reg != D_DX){				t->right->reg = D_DX;				reg[D_DX]++;			}else if(reg[D_DX] == 0)				fatal(Z, "vlong mul DX botch");		}		if(m)			sugen(l, t, 8);		else			loadpair(l, t);		if(t->left->reg != D_AX) {			c = &nod3;			regsalloc(c, t->left);			gmove(&nod1, c);			gmove(t->left, &nod1);			zapreg(t->left);		}		if(t->right->reg != D_DX) {			d = &nod4;			regsalloc(d, t->right);			gmove(&nod2, d);			gmove(t->right, &nod2);			zapreg(t->right);		}		if(c != Z || d != Z) {			s = regpair(Z, n);			s->left = &nod1;			s->right = &nod2;		}		else			s = t;		if(r->op == OCONST) {			if(hi64v(r) == 0)				biggen(s, r, Z, 0, mulc32, nil);			else				biggen(s, r, Z, 0, mulc64, nil);		}		else			biggen(s, r, Z, 0, mull, nil);		instpair(t, Z);		if(c != Z) {			gmove(&nod1, t->left);			gmove(&nod3, &nod1);		}		if(d != Z) {			gmove(&nod2, t->right);			gmove(&nod4, &nod2);		}		if(r->op == OREGPAIR)			freepair(r);		if(!m)			storepair(t, l, 0);		if(l == &nod5)			regfree(l);		if(!dr) {			if(nn != Z)				storepair(t, nn, 1);			else				freepair(t);		}		return 1;	case OASADD:		args = ADDargs;		goto vasop;	case OASAND:		args = ANDargs;		goto vasop;	case OASOR:		args = ORargs;		goto vasop;	case OASSUB:		args = SUBargs;		goto vasop;	case OASXOR:		args = XORargs;		goto vasop;	vasop:		l = n->left;		r = n->right;		dr = nn != Z && nn->op == OREGPAIR;		m = 0;		if(l->complex > r->complex) {			if(!vaddr(l, 1)) {				reglcgen(&nod1, l, Z);				l = &nod1;			}			if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {				if(dr)					t = nn;				else					t = regpair(Z, r);				sugen(r, t, 8);				r = t;				m = 1;			}		}		else {			if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {				if(dr)					t = nn;				else					t = regpair(Z, r);				sugen(r, t, 8);				r = t;				m = 1;			}			if(!vaddr(l, 1)) {				reglcgen(&nod1, l, Z);				l = &nod1;			}		}		if(nn != Z) {			if(n->op == OASSUB)				biggen(l, r, Z, 0, sub10, args);			else				biggen(r, l, Z, 0, binoptmp, args);			storepair(r, l, 0);		}		else {			if(m)				biggen(l, r, Z, 0, binop00, args);			else				biggen(l, r, Z, 0, binoptmp, args);		}		if(l == &nod1)			regfree(&nod1);		if(m) {			if(nn == Z)				freepair(r);			else if(!dr)				storepair(r, nn, 1);		}		return 1;	case OASASHL:		args = nil;		optab = asshlltab;		goto assh;	case OASLSHR:		args = shrlargs;		optab = asshrltab;		goto assh;	case OASASHR:		args = sarlargs;		optab = asshrltab;		goto assh;	assh:		c = Z;		l = n->left;		r = n->right;		if(r->op == OCONST) {			m = r->vconst & 63;			if(m < 32)				m = SAclo;			else if(m == 32)				m = SAc32;			else				m = SAchi;		}		else			m = SAgen;		if(l->complex > r->complex) {			if(!vaddr(l, 0)) {				reglcgen(&nod1, l, Z);				l = &nod1;			}			if(m == SAgen) {				t = &nod2;				if(l->reg == D_CX) {					regalloc(t, r, Z);					gmove(l, t);					l->reg = t->reg;					t->reg = D_CX;				}				else					c = snarfreg(nn, t, D_CX, r, &nod3);				cgen(r, t);				r = t;			}		}		else {			if(m == SAgen) {				t = &nod2;				c = snarfreg(nn, t, D_CX, r, &nod3);				cgen(r, t);				r = t;			}			if(!vaddr(l, 0)) {				reglcgen(&nod1, l, Z);				l = &nod1;			}		}		if(nn != Z) {			m += SAdgen - SAgen;			d = regpair(nn, n);			instpair(d, Z);			biggen(l, r, d, 0, optab[m], args);			if(l == &nod1) {				regfree(&nod1);				l = Z;			}			if(r == &nod2 && c == Z) {				regfree(&nod2);				r = Z;			}			if(d != nn)				storepair(d, nn, 1);		}		else			biggen(l, r, Z, 0, optab[m], args);		if(c != Z) {			gins(AMOVL, c, r);			regfree(c);		}		if(l == &nod1)			regfree(&nod1);		if(r == &nod2)			regfree(&nod2);		return 1;	case OPOSTINC:		args = ADDargs;		cp = incdecpost;		goto vinc;	case OPOSTDEC:		args = SUBargs;		cp = incdecpost;		goto vinc;	case OPREINC:		args = ADDargs;		cp = incdecpre;		goto vinc;	case OPREDEC:		args = SUBargs;		cp = incdecpre;		goto vinc;	vinc:		l = n->left;		if(!vaddr(l, 1)) {			reglcgen(&nod1, l, Z);			l = &nod1;		}				if(nn != Z) {			d = regpair(nn, n);			instpair(d, Z);			biggen(l, Z, d, 0, cp, args);			if(l == &nod1) {				regfree(&nod1);				l = Z;			}			if(d != nn)				storepair(d, nn, 1);		}		else			biggen(l, Z, Z, 0, incdec, args);		if(l == &nod1)			regfree(&nod1);		return 1;	case OCAST:		l = n->left;		if(typev[l->type->etype]) {			if(!vaddr(l, 1)) {				if(l->complex + 1 > nn->complex) {					d = regpair(Z, l);					sugen(l, d, 8);					if(!vaddr(nn, 1)) {						reglcgen(&nod1, nn, Z);						r = &nod1;					}					else						r = nn;				}				else {					if(!vaddr(nn, 1)) {						reglcgen(&nod1, nn, Z);						r = &nod1;					}					else						r = nn;					d = regpair(Z, l);					sugen(l, d, 8);				}//				d->left->type = r->type;				d->left->type = types[TLONG];				gmove(d->left, r);				freepair(d);			}			else {				if(nn->op != OREGISTER && !vaddr(nn, 1)) {					reglcgen(&nod1, nn, Z);					r = &nod1;				}				else					r = nn;//				l->type = r->type;				l->type = types[TLONG];				gmove(l, r);			}			if(r != nn)				regfree(r);		}		else {			if(typeu[l->type->etype] || cond(l->op))				si = TUNSIGNED;			else				si = TSIGNED;			regalloc(&nod1, l, Z);			cgen(l, &nod1);			if(nn->op == OREGPAIR) {				m = instpair(nn, &nod1);				biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);			}			else {				m = 0;				if(!vaddr(nn, si != TSIGNED)) {					dt = nn->type;					nn->type = types[TLONG];					reglcgen(&nod2, nn, Z);					nn->type = dt;					nn = &nod2;				}				dt = nn->type;				nn->type = types[TLONG];				biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);				nn->type = dt;				if(nn == &nod2)					regfree(&nod2);			}			if(!m)				regfree(&nod1);		}		return 1;	default:		if(n->op == OREGPAIR) {			storepair(n, nn, 1);			return 1;		}		if(nn->op == OREGPAIR) {			loadpair(n, nn);			return 1;		}		return 0;	}finished:	if(d != nn)		storepair(d, nn, 1);	return 1;}voidtestv(Node *n, int true){	Type *t;	Node *nn, nod, *b;	if(machcap(Z)) {		b = &nod;		b->op = true ? ONE : OEQ;		b->left = n;		b->right = new(0, Z, Z);		*b->right = *nodconst(0);		b->right->type = n->type;		b->type = types[TLONG];		cgen64(b, Z);		return;	}	switch(n->op) {	case OINDREG:	case ONAME:		biggen(n, Z, Z, true, testi, nil);		break;	default:		n = vfunc(n, n);		if(n->addable >= INDEXED) {			t = n->type;			n->type = types[TLONG];			reglcgen(&nod, n, Z);			n->type = t;			n = &nod;			biggen(n, Z, Z, true, testi, nil);			if(n == &nod)				regfree(n);		}		else {			nn = regpair(Z, n);			sugen(n, nn, 8);			biggen(nn, Z, Z, true, testi, nil);			freepair(nn);		}	}}

⌨️ 快捷键说明

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