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

📄 cgen64.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	{V_T1, Vins, AMOVL, O_t_hi, O_l_hi},	{V_T1, Vins, AMOVL, O_t_lo, O_l_lo},	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},	{V_F1, Vins, ASARL, C31, O_t_hi},	{V_F1, Vins, AMOVL, O_t_lo, O_l_lo},	{V_F1, Vins, AMOVL, O_t_hi, O_l_hi},	{Vend},};static uchar	(*asshrltab[])[VLEN] ={	asshrlgen,	asshrlclo,	asshrlc32,	asshrlchi,	asdshrlgen,	asdshrlclo,	asdshrlc32,	asdshrlchi,};static uchar	shrlargs[]	= { ASHRL, 1 };static uchar	sarlargs[]	= { ASARL, 0 };/* ++ -- */static uchar	incdec[][VLEN] ={	{Vinsx, Bop0, C01, O_l_lo},	{Vinsx, Bop1, C00, O_l_hi, Vend},};/* ++ -- *p */static uchar	incdecpre[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsx, Bop0, C01, O_t_lo},	{Vinsx, Bop1, C00, O_t_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vins, AMOVL, O_t_hi, O_l_hi, Vend},};/* *p ++ -- */static uchar	incdecpost[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsx, Bop0, C01, O_l_lo},	{Vinsx, Bop1, C00, O_l_hi, Vend},};/* binop rp, rp */static uchar	binop00[][VLEN] ={	{Vinsx, Bop0, O_r_lo, O_l_lo},	{Vinsx, Bop1, O_r_hi, O_l_hi, Vend},	{Vend},};/* binop rp, addr */static uchar	binoptmp[][VLEN] ={	{V_a0, Vins, AMOVL, O_r_lo, O_r0},	{Vinsx, Bop0, O_r0, O_l_lo},	{Vins, AMOVL, O_r_hi, O_r0},	{Vinsx, Bop1, O_r0, O_l_hi},	{V_f0, Vend},};/* binop t = *a op *b */static uchar	binop11[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{Vinsx, Bop0, O_r_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsx, Bop1, O_r_hi, O_t_hi, Vend},};/* binop t = rp +- c */static uchar	add0c[][VLEN] ={	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},	{V_r_lo_f, Vamv, Bop0, Bop1},	{Vinsx, Bop1, O_r_hi, O_l_hi},	{Vend},};/* binop t = rp & c */static uchar	and0c[][VLEN] ={	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},	{V_r_lo_f, Vins, AMOVL, C00, O_l_lo},	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},	{V_r_hi_f, Vins, AMOVL, C00, O_l_hi},	{Vend},};/* binop t = rp | c */static uchar	or0c[][VLEN] ={	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},	{Vend},};/* binop t = c - rp */static uchar	sub10[][VLEN] ={	{V_a0, Vins, AMOVL, O_l_lo, O_r0},	{Vinsx, Bop0, O_r_lo, O_r0},	{Vins, AMOVL, O_l_hi, O_r_lo},	{Vinsx, Bop1, O_r_hi, O_r_lo},	{Vspazz, V_f0, Vend},};/* binop t = c + *b */static uchar	addca[][VLEN] ={	{Vins, AMOVL, O_r_lo, O_t_lo},	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},	{V_l_lo_f, Vamv, Bop0, Bop1},	{Vins, AMOVL, O_r_hi, O_t_hi},	{Vinsx, Bop1, O_l_hi, O_t_hi},	{Vend},};/* binop t = c & *b */static uchar	andca[][VLEN] ={	{V_l_lo_t, Vins, AMOVL, O_r_lo, O_t_lo},	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},	{V_l_lo_f, Vzero, O_t_lo},	{V_l_hi_t, Vins, AMOVL, O_r_hi, O_t_hi},	{V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},	{V_l_hi_f, Vzero, O_t_hi},	{Vend},};/* binop t = c | *b */static uchar	orca[][VLEN] ={	{Vins, AMOVL, O_r_lo, O_t_lo},	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},	{Vins, AMOVL, O_r_hi, O_t_hi},	{V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},	{Vend},};/* binop t = c - *b */static uchar	subca[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsx, Bop0, O_r_lo, O_t_lo},	{Vinsx, Bop1, O_r_hi, O_t_hi},	{Vend},};/* binop t = *a +- c */static uchar	addac[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},	{V_r_lo_f, Vamv, Bop0, Bop1},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsx, Bop1, O_r_hi, O_t_hi},	{Vend},};/* binop t = *a | c */static uchar	orac[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_t_hi},	{Vend},};/* binop t = *a & c */static uchar	andac[][VLEN] ={	{V_r_lo_t, Vins, AMOVL, O_l_lo, O_t_lo},	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},	{V_r_lo_f, Vzero, O_t_lo},	{V_r_hi_t, Vins, AMOVL, O_l_hi, O_t_hi},	{V_r_hi_t, Vinsx, Bop0, O_r_hi, O_t_hi},	{V_r_hi_f, Vzero, O_t_hi},	{Vend},};static uchar	ADDargs[]	= { AADDL, AADCL };static uchar	ANDargs[]	= { AANDL, AANDL };static uchar	ORargs[]	= { AORL, AORL };static uchar	SUBargs[]	= { ASUBL, ASBBL };static uchar	XORargs[]	= { AXORL, AXORL };static uchar	(*ADDtab[])[VLEN] ={	add0c, addca, addac,};static uchar	(*ANDtab[])[VLEN] ={	and0c, andca, andac,};static uchar	(*ORtab[])[VLEN] ={	or0c, orca, orac,};static uchar	(*SUBtab[])[VLEN] ={	add0c, subca, addac,};/* mul of const32 */static uchar	mulc32[][VLEN] ={	{V_a0, Vop, ONE, O_l_hi, C00},	{V_s0, Vins, AMOVL, O_r_lo, O_r0},	{Vins, AMULL, O_r0, O_Zop},	{Vgo, V_p0, V_s0},	{Vins, AMOVL, O_l_hi, O_r0},	{Vmul, O_r_lo, O_r0},	{Vins, AMOVL, O_r_lo, O_l_hi},	{Vins, AMULL, O_l_hi, O_Zop},	{Vins, AADDL, O_r0, O_l_hi},	{V_f0, V_p0, Vend},};/* mul of const64 */static uchar	mulc64[][VLEN] ={	{V_a0, Vins, AMOVL, O_r_hi, O_r0},	{Vop, OOR, O_l_hi, O_r0},	{Vop, ONE, O_r0, C00},	{V_s0, Vins, AMOVL, O_r_lo, O_r0},	{Vins, AMULL, O_r0, O_Zop},	{Vgo, V_p0, V_s0},	{Vmul, O_r_lo, O_l_hi},	{Vins, AMOVL, O_l_lo, O_r0},	{Vmul, O_r_hi, O_r0},	{Vins, AADDL, O_l_hi, O_r0},	{Vins, AMOVL, O_r_lo, O_l_hi},	{Vins, AMULL, O_l_hi, O_Zop},	{Vins, AADDL, O_r0, O_l_hi},	{V_f0, V_p0, Vend},};/* mul general */static uchar	mull[][VLEN] ={	{V_a0, Vins, AMOVL, O_r_hi, O_r0},	{Vop, OOR, O_l_hi, O_r0},	{Vop, ONE, O_r0, C00},	{V_s0, Vins, AMOVL, O_r_lo, O_r0},	{Vins, AMULL, O_r0, O_Zop},	{Vgo, V_p0, V_s0},	{Vins, AIMULL, O_r_lo, O_l_hi},	{Vins, AMOVL, O_l_lo, O_r0},	{Vins, AIMULL, O_r_hi, O_r0},	{Vins, AADDL, O_l_hi, O_r0},	{Vins, AMOVL, O_r_lo, O_l_hi},	{Vins, AMULL, O_l_hi, O_Zop},	{Vins, AADDL, O_r0, O_l_hi},	{V_f0, V_p0, Vend},};/* cast rp l to rp t */static uchar	castrp[][VLEN] ={	{Vmv, O_l, O_t_lo},	{VT, Vins, AMOVL, O_t_lo, O_t_hi},	{VT, Vins, ASARL, C31, O_t_hi},	{VF, Vzero, O_t_hi},	{Vend},};/* cast rp l to addr t */static uchar	castrpa[][VLEN] ={	{VT, V_a0, Vmv, O_l, O_r0},	{VT, Vins, AMOVL, O_r0, O_t_lo},	{VT, Vins, ASARL, C31, O_r0},	{VT, Vins, AMOVL, O_r0, O_t_hi},	{VT, V_f0},	{VF, Vmv, O_l, O_t_lo},	{VF, Vzero, O_t_hi},	{Vend},};static uchar	netab0i[][VLEN] ={	{Vop, ONE, O_l_lo, O_r_lo},	{V_s0, Vop, ONE, O_l_hi, O_r_hi},	{V_s1, Vgo, V_s2, Vgo, V_s3},	{VF, V_p0, V_p1, VT, V_p2},	{Vgo, V_p3},	{VT, V_p0, V_p1, VF, V_p2},	{Vend},};static uchar	netabii[][VLEN] ={	{V_a0, Vins, AMOVL, O_l_lo, O_r0},	{Vop, ONE, O_r0, O_r_lo},	{V_s0, Vins, AMOVL, O_l_hi, O_r0},	{Vop, ONE, O_r0, O_r_hi},	{V_s1, Vgo, V_s2, Vgo, V_s3},	{VF, V_p0, V_p1, VT, V_p2},	{Vgo, V_p3},	{VT, V_p0, V_p1, VF, V_p2},	{V_f0, Vend},};static uchar	cmptab0i[][VLEN] ={	{Vopx, Bop0, O_l_hi, O_r_hi},	{V_s0, Vins0, AJNE},	{V_s1, Vopx, Bop1, O_l_lo, O_r_lo},	{V_s2, Vgo, V_s3, Vgo, V_s4},	{VT, V_p1, V_p3},	{VF, V_p0, V_p2},	{Vgo, V_p4},	{VT, V_p0, V_p2},	{VF, V_p1, V_p3},	{Vend},};static uchar	cmptabii[][VLEN] ={	{V_a0, Vins, AMOVL, O_l_hi, O_r0},	{Vopx, Bop0, O_r0, O_r_hi},	{V_s0, Vins0, AJNE},	{V_s1, Vins, AMOVL, O_l_lo, O_r0},	{Vopx, Bop1, O_r0, O_r_lo},	{V_s2, Vgo, V_s3, Vgo, V_s4},	{VT, V_p1, V_p3},	{VF, V_p0, V_p2},	{Vgo, V_p4},	{VT, V_p0, V_p2},	{VF, V_p1, V_p3},	{V_f0, Vend},};static uchar	(*NEtab[])[VLEN] ={	netab0i, netabii,};static uchar	(*cmptab[])[VLEN] ={	cmptab0i, cmptabii,};static uchar	GEargs[]	= { OGT, OHS };static uchar	GTargs[]	= { OGT, OHI };static uchar	HIargs[]	= { OHI, OHI };static uchar	HSargs[]	= { OHI, OHS };/* Big Generator */static voidbiggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a){	int i, j, g, oc, op, lo, ro, to, xo, *xp;	Type *lt;	Prog *pr[VOPS];	Node *ot, *tl, *tr, tmps[2];	uchar *c, (*cp)[VLEN], args[VARGS];	if(a != nil)		memmove(args, a, VARGS);//print("biggen %d %d %d\n", args[0], args[1], args[2]);//if(l) prtree(l, "l");//if(r) prtree(r, "r");//if(t) prtree(t, "t");	lo = ro = to = 0;	cp = code;	for (;;) {		c = *cp++;		g = 1;		i = 0;//print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]);		for(;;) {			switch(op = c[i]) {			case Vgo:				if(g)					gbranch(OGOTO);				i++;				break;			case Vamv:				i += 3;				if(i > VLEN) {					diag(l, "bad Vop");					return;				}				if(g)					args[c[i - 1]] = args[c[i - 2]];				break;			case Vzero:				i += 2;				if(i > VLEN) {					diag(l, "bad Vop");					return;				}				j = i - 1;				goto op;			case Vspazz:	// nasty hack to save a reg in SUB//print("spazz\n");				if(g) {//print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);					ot = r->right;					r->right = r->left;					tl = new(0, Z, Z);					*tl = tmps[0];					r->left = tl;					tmps[0] = *ot;//print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);				}				i++;				break;			case Vmv:			case Vmul:			case Vshll:				i += 3;				if(i > VLEN) {					diag(l, "bad Vop");					return;				}				j = i - 2;				goto op;			case Vins0:				i += 2;				if(i > VLEN) {					diag(l, "bad Vop");					return;				}				gins(c[i - 1], Z, Z);				break;			case Vop:			case Vopx:			case Vins:			case Vinsl:			case Vinsr:			case Vinsla:			case Vinsra:			case Vinsx:				i += 4;				if(i > VLEN) {					diag(l, "bad Vop");					return;				}				j = i - 2;				goto op;			op:				if(!g)					break;				tl = Z;				tr = Z;				for(; j < i; j++) {					switch(c[j]) {					case C00:						ot = nodconst(0);						break;					case C01:						ot = nodconst(1);						break;					case C31:						ot = nodconst(31);						break;					case C32:						ot = nodconst(32);						break;					case O_l:					case O_l_lo:						ot = l; xp = &lo; xo = 0;						goto op0;					case O_l_hi:						ot = l; xp = &lo; xo = SZ_LONG;						goto op0;					case O_r:					case O_r_lo:						ot = r; xp = &ro; xo = 0;						goto op0;					case O_r_hi:						ot = r; xp = &ro; xo = SZ_LONG;						goto op0;					case O_t_lo:						ot = t; xp = &to; xo = 0;						goto op0;					case O_t_hi:						ot = t; xp = &to; xo = SZ_LONG;						goto op0;					case O_l_rp:						ot = l;						break;					case O_r_rp:						ot = r;						break;					case O_t_rp:						ot = t;						break;					case O_r0:					case O_r1:						ot = &tmps[c[j] - O_r0];						break;					case O_Zop:						ot = Z;						break;					op0:						switch(ot->op) {						case OCONST:							if(xo)								ot = hi64(ot);							else								ot = lo64(ot);							break;						case OREGPAIR:							if(xo)								ot = ot->right;							else								ot = ot->left;							break;						case OREGISTER:							break;						default:							if(xo != *xp) {								ot->xoffset += xo - *xp;								*xp = xo;							}						}						break;										default:						diag(l, "bad V_lop");						return;					}					if(tl == nil)						tl = ot;					else						tr = ot;				}				if(op == Vzero) {					zeroregm(tl);					break;				}				oc = c[i - 3];				if(op == Vinsx || op == Vopx) {//print("%d -> %d\n", oc, args[oc]);					oc = args[oc];				}				else {					switch(oc) {					case O_a0:					case O_a1:						oc = args[oc - O_a0];						break;					}				}				switch(op) {				case Vmul:					mulgen(tr->type, tl, tr);					break;				case Vmv:					gmove(tl, tr);					break;				case Vshll:					shiftit(tr->type, tl, tr);					break;				case Vop:				case Vopx:					gopcode(oc, types[TULONG], tl, tr);					break;				case Vins:				case Vinsx:					gins(oc, tl, tr);					break;				case Vinsl:					gins(oc, tl, tr->right);					p->from.index = tr->left->reg;					break;				case Vinsr:					gins(oc, tl, tr->left);					p->from.index = tr->right->reg;					break;				case Vinsla:					gins(oc, tl, tr + 1);					p->from.index = tr->reg;					break;				case Vinsra:					gins(oc, tl, tr);					p->from.index = (tr + 1)->reg;					break;				}				break;			case VT:				g = true;				i++;				break;			case VF:				g = !true;				i++;				break;			case V_T0: case V_T1:				g = args[op - V_T0];				i++;				break;			case V_F0: case V_F1:				g = !args[op - V_F0];				i++;				break;			case V_C0: case V_C1:				if(g)					args[op - V_C0] = 0;				i++;				break;			case V_S0: case V_S1:				if(g)					args[op - V_S0] = 1;				i++;				break;			case V_l_lo_f:				g = lo64v(l) == 0;				i++;				break;			case V_l_hi_f:				g = hi64v(l) == 0;				i++;				break;			case V_l_lo_t:				g = lo64v(l) != 0;				i++;				break;			case V_l_hi_t:				g = hi64v(l) != 0;				i++;				break;			case V_l_lo_u:				g = lo64v(l) >= 0;				i++;				break;			case V_l_hi_u:				g = hi64v(l) >= 0;				i++;				break;			case V_r_lo_f:				g = lo64v(r) == 0;				i++;				break;			case V_r_hi_f:				g = hi64v(r) == 0;				i++;				break;			case V_r_lo_t:				g = lo64v(r) != 0;				i++;				break;			case V_r_hi_t:				g = hi64v(r) != 0;				i++;				break;			case V_r_lo_u:				g = lo64v(r) >= 0;				i++;				break;			case V_r_hi_u:				g = hi64v(r) >= 0;				i++;				break;			case Vend:				goto out;			case V_a0: case V_a1:				if(g) {					lt = l->type;					l->type = types[TULONG];					regalloc(&tmps[op - V_a0], l, Z);					l->type = lt;				}				i++;				break;			case V_f0: case V_f1:				if(g)					regfree(&tmps[op - V_f0]);				i++;				break;			case V_p0: case V_p1: case V_p2: case V_p3: case V_p4:				if(g)					patch(pr[op - V_p0], pc);				i++;				break;			case V_s0: case V_s1: case V_s2: case V_s3: case V_s4:				if(g)					pr[op - V_s0] = p;				i++;				break;			default:				diag(l, "bad biggen: %d", op);				return;			}			if(i == VLEN || c[i] == 0)				break;		}	}out:	if(lo)		l->xoffset -= lo;	if(ro)		r->xoffset -= ro;	if(to)		t->xoffset -= to;}intcgen64(Node *n, Node *nn){	Type *dt;	uchar *args, (*cp)[VLEN], (**optab)[VLEN];	int li, ri, lri, dr, si, m, op, sh, cmp, true;	Node *c, *d, *l, *r, *t, *s, nod1, nod2, nod3, nod4, nod5;	if(debug['g']) {		prtree(nn, "cgen64 lhs");		prtree(n, "cgen64");		print("AX = %d\n", reg[D_AX]);	}	cmp = 0;	sh = 0;	switch(n->op) {	case ONEG:		d = regpair(nn, n);		sugen(n->left, d, 8);		gins(ANOTL, Z, d->right);		gins(ANEGL, Z, d->left);		gins(ASBBL, nodconst(-1), d->right);		break;	case OCOM:		if(!vaddr(n->left, 0) || !vaddr(nn, 0))			d = regpair(nn, n);		else			return 0;		sugen(n->left, d, 8);		gins(ANOTL, Z, d->left);		gins(ANOTL, Z, d->right);		break;	case OADD:		optab = ADDtab;		args = ADDargs;		goto twoop;	case OAND:		optab = ANDtab;		args = ANDargs;		goto twoop;	case OOR:		optab = ORtab;		args = ORargs;		goto twoop;	case OSUB:		optab = SUBtab;		args = SUBargs;		goto twoop;	case OXOR:		optab = ORtab;		args = XORargs;		goto twoop;	case OASHL:		sh = 1;		args = nil;		optab = shlltab;		goto twoop;	case OLSHR:		sh = 1;		args = shrlargs;		optab = shrltab;		goto twoop;	case OASHR:		sh = 1;		args = sarlargs;		optab = shrltab;		goto twoop;	case OEQ:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case ONE:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OLE:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OLT:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OGE:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OGT:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OHI:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OHS:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OLO:		cmp = 1;		args = nil;		optab = nil;		goto twoop;	case OLS:		cmp = 1;		args = nil;		optab = nil;		goto twoop;twoop:		dr = nn != Z && nn->op == OREGPAIR;		l = vfunc(n->left, nn);		if(sh)			r = n->right;		else			r = vfunc(n->right, nn);		li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;		ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;#define	IMM(l, r)	((l) | ((r) << 1))		lri = IMM(li, ri);		/* find out what is so easy about some operands */		if(li)			li = whatof(l, sh | cmp);		if(ri)			ri = whatof(r, cmp);		if(sh)			goto shift;		if(cmp)			goto cmp;		/* evaluate hard subexps, stealing nn if possible. */		switch(lri) {		case IMM(0, 0):		bin00:			if(l->complex > r->complex) {				if(dr)					t = nn;				else					t = regpair(Z, n);				sugen(l, t, 8);				l = t;				t = regpair(Z, n);				sugen(r, t, 8);				r = t;			}			else {				t = regpair(Z, n);				sugen(r, t, 8);				r = t;				if(dr)					t = nn;				else					t = regpair(Z, n);				sugen(l, t, 8);

⌨️ 快捷键说明

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