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

📄 cgen64.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "gc.h"voidzeroregm(Node *n){	gins(AMOVL, nodconst(0), n);}/* do we need to load the address of a vlong? */intvaddr(Node *n, int a){	switch(n->op) {	case ONAME:		if(a)			return 1;		return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);	case OCONST:	case OREGISTER:	case OINDREG:		return 1;	}	return 0;}longhi64v(Node *n){	if(align(0, types[TCHAR], Aarg1))	/* isbigendian */		return (long)(n->vconst) & ~0L;	else		return (long)((uvlong)n->vconst>>32) & ~0L;}longlo64v(Node *n){	if(align(0, types[TCHAR], Aarg1))	/* isbigendian */		return (long)((uvlong)n->vconst>>32) & ~0L;	else		return (long)(n->vconst) & ~0L;}Node *hi64(Node *n){	return nodconst(hi64v(n));}Node *lo64(Node *n){	return nodconst(lo64v(n));}static Node *anonreg(void){	Node *n;	n = new(OREGISTER, Z, Z);	n->reg = D_NONE;	n->type = types[TLONG];	return n;}static Node *regpair(Node *n, Node *t){	Node *r;	if(n != Z && n->op == OREGPAIR)		return n;	r = new(OREGPAIR, anonreg(), anonreg());	if(n != Z)		r->type = n->type;	else		r->type = t->type;	return r;}static voidevacaxdx(Node *r){	Node nod1, nod2;	if(r->reg == D_AX || r->reg == D_DX) {		reg[D_AX]++;		reg[D_DX]++;		/*		 * this is just an optim that should		 * check for spill		 */		r->type = types[TULONG];		regalloc(&nod1, r, Z);		nodreg(&nod2, Z, r->reg);		gins(AMOVL, &nod2, &nod1);		regfree(r);		r->reg = nod1.reg;		reg[D_AX]--;		reg[D_DX]--;	}}/* lazy instantiation of register pair */static intinstpair(Node *n, Node *l){	int r;	r = 0;	if(n->left->reg == D_NONE) {		if(l != Z) {			n->left->reg = l->reg;			r = 1;		}		else			regalloc(n->left, n->left, Z);	}	if(n->right->reg == D_NONE)		regalloc(n->right, n->right, Z);	return r;}static voidzapreg(Node *n){	if(n->reg != D_NONE) {		regfree(n);		n->reg = D_NONE;	}}static voidfreepair(Node *n){	regfree(n->left);	regfree(n->right);}/* n is not OREGPAIR, nn is */voidloadpair(Node *n, Node *nn){	Node nod;	instpair(nn, Z);	if(n->op == OCONST) {		gins(AMOVL, lo64(n), nn->left);		n->xoffset += SZ_LONG;		gins(AMOVL, hi64(n), nn->right);		n->xoffset -= SZ_LONG;		return;	}	if(!vaddr(n, 0)) {		/* steal the right register for the laddr */		nod = regnode;		nod.reg = nn->right->reg;		lcgen(n, &nod);		n = &nod;		regind(n, n);		n->xoffset = 0;	}	gins(AMOVL, n, nn->left);	n->xoffset += SZ_LONG;	gins(AMOVL, n, nn->right);	n->xoffset -= SZ_LONG;}/* n is OREGPAIR, nn is not */static voidstorepair(Node *n, Node *nn, int f){	Node nod;	if(!vaddr(nn, 0)) {		reglcgen(&nod, nn, Z);		nn = &nod;	}	gins(AMOVL, n->left, nn);	nn->xoffset += SZ_LONG;	gins(AMOVL, n->right, nn);	nn->xoffset -= SZ_LONG;	if(nn == &nod)		regfree(&nod);	if(f)		freepair(n);}/* generate a cast t from n to tt */static voidcast(Node *n, Type *t, Node *nn){	Node *r;	r = new(OCAST, n, Z);	r->type = t;	sugen(r, nn, 8);}static voidswapregs(Node *a, Node *b){	int t;	t = a->reg;	a->reg = b->reg;	b->reg = t;}static voidswappairs(Node *a, Node *b){	swapregs(a->left, b->left);	swapregs(a->right, b->right);}static intsaveme(Node *n){	int r;	r = n->reg;	return r >= D_AX && r <= D_DI;}static voidsaveit(Node *n, Node *t, Node *r){	Node nod;	if(saveme(n)) {		t->reg = n->reg;		gins(AMOVL, t, r);		r->xoffset += SZ_LONG;		if(n->reg == D_AX) {			regalloc(&nod, n, Z);			regfree(n);			n->reg = nod.reg;		}	}}static voidrestoreit(Node *n, Node *t, Node *r){	if(saveme(n)) {		t->reg = n->reg;		gins(AMOVL, r, t);		r->xoffset += SZ_LONG;	}}enum{/* 4 only, see WW */	WNONE	= 0,	WCONST,	WADDR,	WHARD,};static intwhatof(Node *n, int a){	if(n->op == OCONST)		return WCONST;	return !vaddr(n, a) ? WHARD : WADDR;}/* can upgrade an extern to addr for AND */static intreduxv(Node *n){	return lo64v(n) == 0 || hi64v(n) == 0;}intcond(int op){	switch(op) {	case OANDAND:	case OOROR:	case ONOT:		return 1;	case OEQ:	case ONE:	case OLE:	case OLT:	case OGE:	case OGT:	case OHI:	case OHS:	case OLO:	case OLS:		return 1;	}	return 0;}/* * for a func operand call it and then return * the safe node */static Node *vfunc(Node *n, Node *nn){	Node *t;	if(n->op != OFUNC)		return n;	t = new(0, Z, Z);	if(nn == Z || nn == nodret)		nn = n;	regsalloc(t, nn);	sugen(n, t, 8);	return t;}static intforcereg(Node *d, int r, int o, Node *t){	int a;	if(d->reg != D_NONE)		diag(Z, "force alloc");	d->reg = r;	a = 0;	if(reg[r]) {		reg[o]++;		regalloc(t, d, Z);		a = 1;		gins(AMOVL, d, t);		reg[o]--;	}	reg[r]++;	return a;}/* try to steal a reg */static intgetreg(Node **np, Node *t, int r){	Node *n, *p;	n = *np;	if(n->reg == r) {		p = new(0, Z, Z);		regalloc(p, n, Z);		gins(AMOVL, n, p);		*t = *n;		*np = p;		return 1;	}	return 0;}static Node *snarfreg(Node *n, Node *t, int r, Node *d, Node *c){	if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) {		if(nodreg(t, Z, r)) {			regalloc(c, d, Z);			gins(AMOVL, t, c);			reg[r]++;			return c;		}		reg[r]++;	}	return Z;}enum{	Vstart	= OEND,	Vgo,	Vamv,	Vmv,	Vzero,	Vop,	Vopx,	Vins,	Vins0,	Vinsl,	Vinsr,	Vinsla,	Vinsra,	Vinsx,	Vmul,	Vshll,	VT,	VF,	V_l_lo_f,	V_l_hi_f,	V_l_lo_t,	V_l_hi_t,	V_l_lo_u,	V_l_hi_u,	V_r_lo_f,	V_r_hi_f,	V_r_lo_t,	V_r_hi_t,	V_r_lo_u,	V_r_hi_u,	Vspazz,	Vend,	V_T0,	V_T1,	V_F0,	V_F1,	V_a0,	V_a1,	V_f0,	V_f1,	V_p0,	V_p1,	V_p2,	V_p3,	V_p4,	V_s0,	V_s1,	V_s2,	V_s3,	V_s4,	C00,	C01,	C31,	C32,	O_l_lo,	O_l_hi,	O_r_lo,	O_r_hi,	O_t_lo,	O_t_hi,	O_l,	O_r,	O_l_rp,	O_r_rp,	O_t_rp,	O_r0,	O_r1,	O_Zop,	O_a0,	O_a1,	V_C0,	V_C1,	V_S0,	V_S1,	VOPS	= 5,	VLEN	= 5,	VARGS	= 2,	S00	= 0,	Sc0,	Sc1,	Sc2,	Sac3,	Sac4,	S10,	SAgen	= 0,	SAclo,	SAc32,	SAchi,	SAdgen,	SAdclo,	SAdc32,	SAdchi,	B0c	= 0,	Bca,	Bac,	T0i	= 0,	Tii,	Bop0	= 0,	Bop1,};/* * _testv: * 	CMPL	lo,$0 * 	JNE	true * 	CMPL	hi,$0 * 	JNE	true * 	GOTO	false * false: * 	GOTO	code * true: * 	GOTO	patchme * code: */static uchar	testi[][VLEN] ={	{Vop, ONE, O_l_lo, C00},	{V_s0, Vop, ONE, O_l_hi, C00},	{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},};/* shift left general case */static uchar	shll00[][VLEN] ={	{Vop, OGE, O_r, C32},	{V_s0, Vinsl, ASHLL, O_r, O_l_rp},	{Vins, ASHLL, O_r, O_l_lo, Vgo},	{V_p0, V_s0},	{Vins, ASHLL, O_r, O_l_lo},	{Vins, AMOVL, O_l_lo, O_l_hi},	{Vzero, O_l_lo, V_p0, Vend},};/* shift left rp, const < 32 */static uchar	shllc0[][VLEN] ={	{Vinsl, ASHLL, O_r, O_l_rp},	{Vshll, O_r, O_l_lo, Vend},};/* shift left rp, const == 32 */static uchar	shllc1[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_l_hi},	{Vzero, O_l_lo, Vend},};/* shift left rp, const > 32 */static uchar	shllc2[][VLEN] ={	{Vshll, O_r, O_l_lo},	{Vins, AMOVL, O_l_lo, O_l_hi},	{Vzero, O_l_lo, Vend},};/* shift left addr, const == 32 */static uchar	shllac3[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_hi},	{Vzero, O_t_lo, Vend},};/* shift left addr, const > 32 */static uchar	shllac4[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_hi},	{Vshll, O_r, O_t_hi},	{Vzero, O_t_lo, Vend},};/* shift left of constant */static uchar	shll10[][VLEN] ={	{Vop, OGE, O_r, C32},	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsl, ASHLL, O_r, O_t_rp},	{Vins, ASHLL, O_r, O_t_lo, Vgo},	{V_p0, V_s0},	{Vins, AMOVL, O_l_lo, O_t_hi},	{V_l_lo_t, Vins, ASHLL, O_r, O_t_hi},	{Vzero, O_t_lo, V_p0, Vend},};static uchar	(*shlltab[])[VLEN] ={	shll00,	shllc0,	shllc1,	shllc2,	shllac3,	shllac4,	shll10,};/* shift right general case */static uchar	shrl00[][VLEN] ={	{Vop, OGE, O_r, C32},	{V_s0, Vinsr, ASHRL, O_r, O_l_rp},	{Vins, O_a0, O_r, O_l_hi, Vgo},	{V_p0, V_s0},	{Vins, O_a0, O_r, O_l_hi},	{Vins, AMOVL, O_l_hi, O_l_lo},	{V_T1, Vzero, O_l_hi},	{V_F1, Vins, ASARL, C31, O_l_hi},	{V_p0, Vend},};/* shift right rp, const < 32 */static uchar	shrlc0[][VLEN] ={	{Vinsr, ASHRL, O_r, O_l_rp},	{Vins, O_a0, O_r, O_l_hi, Vend},};/* shift right rp, const == 32 */static uchar	shrlc1[][VLEN] ={	{Vins, AMOVL, O_l_hi, O_l_lo},	{V_T1, Vzero, O_l_hi},	{V_F1, Vins, ASARL, C31, O_l_hi},	{Vend},};/* shift right rp, const > 32 */static uchar	shrlc2[][VLEN] ={	{Vins, O_a0, O_r, O_l_hi},	{Vins, AMOVL, O_l_hi, O_l_lo},	{V_T1, Vzero, O_l_hi},	{V_F1, Vins, ASARL, C31, O_l_hi},	{Vend},};/* shift right addr, const == 32 */static uchar	shrlac3[][VLEN] ={	{Vins, AMOVL, O_l_hi, O_t_lo},	{V_T1, Vzero, O_t_hi},	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},	{V_F1, Vins, ASARL, C31, O_t_hi},	{Vend},};/* shift right addr, const > 32 */static uchar	shrlac4[][VLEN] ={	{Vins, AMOVL, O_l_hi, O_t_lo},	{Vins, O_a0, O_r, O_t_lo},	{V_T1, Vzero, O_t_hi},	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},	{V_F1, Vins, ASARL, C31, O_t_hi},	{Vend},};/* shift right of constant */static uchar	shrl10[][VLEN] ={	{Vop, OGE, O_r, C32},	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsr, ASHRL, O_r, O_t_rp},	{Vins, O_a0, O_r, O_t_hi, Vgo},	{V_p0, V_s0},	{Vins, AMOVL, O_l_hi, O_t_lo},	{V_l_hi_t, Vins, O_a0, O_r, O_t_lo},	{V_l_hi_u, V_S1},	{V_T1, Vzero, O_t_hi, V_p0},	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},	{V_F1, Vins, ASARL, C31, O_t_hi},	{Vend},};static uchar	(*shrltab[])[VLEN] ={	shrl00,	shrlc0,	shrlc1,	shrlc2,	shrlac3,	shrlac4,	shrl10,};/* shift asop left general case */static uchar	asshllgen[][VLEN] ={	{V_a0, V_a1},	{Vop, OGE, O_r, C32},	{V_s0, Vins, AMOVL, O_l_lo, O_r0},	{Vins, AMOVL, O_l_hi, O_r1},	{Vinsla, ASHLL, O_r, O_r0},	{Vins, ASHLL, O_r, O_r0},	{Vins, AMOVL, O_r1, O_l_hi},	{Vins, AMOVL, O_r0, O_l_lo, Vgo},	{V_p0, V_s0},	{Vins, AMOVL, O_l_lo, O_r0},	{Vzero, O_l_lo},	{Vins, ASHLL, O_r, O_r0},	{Vins, AMOVL, O_r0, O_l_hi, V_p0},	{V_f0, V_f1, Vend},};/* shift asop left, const < 32 */static uchar	asshllclo[][VLEN] ={	{V_a0, V_a1},	{Vins, AMOVL, O_l_lo, O_r0},	{Vins, AMOVL, O_l_hi, O_r1},	{Vinsla, ASHLL, O_r, O_r0},	{Vshll, O_r, O_r0},	{Vins, AMOVL, O_r1, O_l_hi},	{Vins, AMOVL, O_r0, O_l_lo},	{V_f0, V_f1, Vend},};/* shift asop left, const == 32 */static uchar	asshllc32[][VLEN] ={	{V_a0},	{Vins, AMOVL, O_l_lo, O_r0},	{Vzero, O_l_lo},	{Vins, AMOVL, O_r0, O_l_hi},	{V_f0, Vend},};/* shift asop left, const > 32 */static uchar	asshllchi[][VLEN] ={	{V_a0},	{Vins, AMOVL, O_l_lo, O_r0},	{Vzero, O_l_lo},	{Vshll, O_r, O_r0},	{Vins, AMOVL, O_r0, O_l_hi},	{V_f0, Vend},};/* shift asop dest left general case */static uchar	asdshllgen[][VLEN] ={	{Vop, OGE, O_r, C32},	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsl, ASHLL, O_r, O_t_rp},	{Vins, ASHLL, O_r, O_t_lo},	{Vins, AMOVL, O_t_hi, O_l_hi},	{Vins, AMOVL, O_t_lo, O_l_lo, Vgo},	{V_p0, V_s0},	{Vins, AMOVL, O_l_lo, O_t_hi},	{Vzero, O_l_lo},	{Vins, ASHLL, O_r, O_t_hi},	{Vzero, O_t_lo},	{Vins, AMOVL, O_t_hi, O_l_hi, V_p0},	{Vend},};/* shift asop dest left, const < 32 */static uchar	asdshllclo[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsl, ASHLL, O_r, O_t_rp},	{Vshll, O_r, O_t_lo},	{Vins, AMOVL, O_t_hi, O_l_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vend},};/* shift asop dest left, const == 32 */static uchar	asdshllc32[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_hi},	{Vzero, O_t_lo},	{Vins, AMOVL, O_t_hi, O_l_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vend},};/* shift asop dest, const > 32 */static uchar	asdshllchi[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_hi},	{Vzero, O_t_lo},	{Vshll, O_r, O_t_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vins, AMOVL, O_t_hi, O_l_hi},	{Vend},};static uchar	(*asshlltab[])[VLEN] ={	asshllgen,	asshllclo,	asshllc32,	asshllchi,	asdshllgen,	asdshllclo,	asdshllc32,	asdshllchi,};/* shift asop right general case */static uchar	asshrlgen[][VLEN] ={	{V_a0, V_a1},	{Vop, OGE, O_r, C32},	{V_s0, Vins, AMOVL, O_l_lo, O_r0},	{Vins, AMOVL, O_l_hi, O_r1},	{Vinsra, ASHRL, O_r, O_r0},	{Vinsx, Bop0, O_r, O_r1},	{Vins, AMOVL, O_r0, O_l_lo},	{Vins, AMOVL, O_r1, O_l_hi, Vgo},	{V_p0, V_s0},	{Vins, AMOVL, O_l_hi, O_r0},	{Vinsx, Bop0, O_r, O_r0},	{V_T1, Vzero, O_l_hi},	{Vins, AMOVL, O_r0, O_l_lo},	{V_F1, Vins, ASARL, C31, O_r0},	{V_F1, Vins, AMOVL, O_r0, O_l_hi},	{V_p0, V_f0, V_f1, Vend},};/* shift asop right, const < 32 */static uchar	asshrlclo[][VLEN] ={	{V_a0, V_a1},	{Vins, AMOVL, O_l_lo, O_r0},	{Vins, AMOVL, O_l_hi, O_r1},	{Vinsra, ASHRL, O_r, O_r0},	{Vinsx, Bop0, O_r, O_r1},	{Vins, AMOVL, O_r0, O_l_lo},	{Vins, AMOVL, O_r1, O_l_hi},	{V_f0, V_f1, Vend},};/* shift asop right, const == 32 */static uchar	asshrlc32[][VLEN] ={	{V_a0},	{Vins, AMOVL, O_l_hi, O_r0},	{V_T1, Vzero, O_l_hi},	{Vins, AMOVL, O_r0, O_l_lo},	{V_F1, Vins, ASARL, C31, O_r0},	{V_F1, Vins, AMOVL, O_r0, O_l_hi},	{V_f0, Vend},};/* shift asop right, const > 32 */static uchar	asshrlchi[][VLEN] ={	{V_a0},	{Vins, AMOVL, O_l_hi, O_r0},	{V_T1, Vzero, O_l_hi},	{Vinsx, Bop0, O_r, O_r0},	{Vins, AMOVL, O_r0, O_l_lo},	{V_F1, Vins, ASARL, C31, O_r0},	{V_F1, Vins, AMOVL, O_r0, O_l_hi},	{V_f0, Vend},};/* shift asop dest right general case */static uchar	asdshrlgen[][VLEN] ={	{Vop, OGE, O_r, C32},	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsr, ASHRL, O_r, O_t_rp},	{Vinsx, Bop0, O_r, O_t_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vins, AMOVL, O_t_hi, O_l_hi, Vgo},	{V_p0, V_s0},	{Vins, AMOVL, O_l_hi, O_t_lo},	{V_T1, Vzero, O_t_hi},	{Vinsx, Bop0, O_r, O_t_lo},	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},	{V_F1, Vins, ASARL, C31, O_t_hi},	{Vins, AMOVL, O_t_hi, O_l_hi, V_p0},	{Vend},};/* shift asop dest right, const < 32 */static uchar	asdshrlclo[][VLEN] ={	{Vins, AMOVL, O_l_lo, O_t_lo},	{Vins, AMOVL, O_l_hi, O_t_hi},	{Vinsr, ASHRL, O_r, O_t_rp},	{Vinsx, Bop0, O_r, O_t_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vins, AMOVL, O_t_hi, O_l_hi},	{Vend},};/* shift asop dest right, const == 32 */static uchar	asdshrlc32[][VLEN] ={	{Vins, AMOVL, O_l_hi, O_t_lo},	{V_T1, Vzero, O_t_hi},	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},	{V_F1, Vins, ASARL, C31, O_t_hi},	{Vins, AMOVL, O_t_lo, O_l_lo},	{Vins, AMOVL, O_t_hi, O_l_hi},	{Vend},};/* shift asop dest, const > 32 */static uchar	asdshrlchi[][VLEN] ={	{Vins, AMOVL, O_l_hi, O_t_lo},	{V_T1, Vzero, O_t_hi},	{Vinsx, Bop0, O_r, O_t_lo},

⌨️ 快捷键说明

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