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

📄 noop.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
				p = q;				break;			}			if(p->from.type != D_REG){				diag("bad instruction %P", p);				break;			}			o = p->as;			q = genIRR(p, ASUBQ, 16LL, NREG, REGSP);			q = genstore(q, AMOVQ, p->from.reg, 8LL, REGSP);			if (o == ADIVL || o == ADIVL || o == AMODL || o == AMODLU)				q->as = AMOVL;			q = genRRR(q, AMOVQ, p->reg, NREG, REGTMP);			if (p->reg == NREG)				q->from.reg = p->to.reg;			/* CALL appropriate */			q1 = prg();			q1->link = q->link;			q->link = q1;			q1->as = AJSR;			q1->line = p->line;			q1->to.type = D_BRANCH;			q1->cond = divsubr(o);			q1->mark |= BRANCH;			q = q1;			q = genRRR(q, AMOVQ, REGTMP, NREG, p->to.reg);			q = genIRR(q, AADDQ, 16LL, NREG, REGSP);			excise(p);			p = q;			break;		/* Attempt to replace {cond. branch, mov} with a cmov */		/* XXX warning: this is all a bit experimental */		case ABEQ:		case ABNE:		case ABGE:		case ABGT:		case ABLE:		case ABLT:		case ABLBC:		case ABLBS:			q = p->link;			if (q == P)				break;			q1 = q->link;			if (q1 != p->cond || q1 == P)				break;/*print("%P\n", q); /* */			if (q->to.type != D_REG)				break;			if (q->from.type != D_REG && (q->from.type != D_CONST || q->from.name != D_NONE))				break;			if (q->mark&LABEL2)				break;/* print("%P\n", q); /* */			if (q->as != AMOVQ)		/* XXX can handle more than this! */				break;			q->as = (p->as^1) + ACMOVEQ-ABEQ;	/* sleazy hack */			q->reg = p->from.reg;		/* XXX check CMOVx operand order! */			excise(p);		/* XXX p's LABEL? */			if (!(q1->mark&LABEL2))				q1->mark &= ~LABEL;			break;		case AFBEQ:		case AFBNE:		case AFBGE:		case AFBGT:		case AFBLE:		case AFBLT:			q = p->link;			if (q == P)				break;			q1 = q->link;			if (q1 != p->cond || q1 == P)				break;			if (q->from.type != D_FREG || q->to.type != D_FREG)				break;/* print("%P\n", q); /* */			if (q->mark&LABEL2)				break;			if (q->as != AMOVT)		/* XXX can handle more than this! */				break;			q->as = (p->as^1) + AFCMOVEQ-AFBEQ;	/* sleazy hack */			q->reg = p->from.reg;		/* XXX check CMOVx operand order! */			excise(p);		/* XXX p's LABEL? */			if (!(q1->mark&LABEL2))				q1->mark &= ~LABEL;			break;		}	}	curtext = P;	q = P;		/* p - 1 */	q1 = firstp;	/* top of block */	o = 0;		/* count of instructions */	for(p = firstp; p != P; p = p1) {		p1 = p->link;		o++;		if(p->mark & NOSCHED){			if(q1 != p){				sched(q1, q);			}			for(; p != P; p = p->link){				if(!(p->mark & NOSCHED))					break;				q = p;			}			p1 = p;			q1 = p;			o = 0;			continue;		}		if(p->mark & (LABEL|SYNC)) {			if(q1 != p)				sched(q1, q);			q1 = p;			o = 1;		}		if(p->mark & (BRANCH|SYNC)) {			sched(q1, p);			q1 = p1;			o = 0;		}		if(o >= NSCHED) {			sched(q1, p);			q1 = p1;			o = 0;		}		q = p;	}}voidnocache(Prog *p){	p->optab = 0;	p->from.class = 0;	p->to.class = 0;}/* XXX use of this may lose important LABEL flags, check that this isn't happening (or fix) */voidexcise(Prog *p){	Prog *q;	q = p->link;	*p = *q;}voidinitdiv(void){	Sym *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;	Prog *p;	s1 = lookup("_divq", 0);	s2 = lookup("_divqu", 0);	s3 = lookup("_modq", 0);	s4 = lookup("_modqu", 0);	s5 = lookup("_divl", 0);	s6 = lookup("_divlu", 0);	s7 = lookup("_modl", 0);	s8 = lookup("_modlu", 0);	for(p = firstp; p != P; p = p->link)		if(p->as == ATEXT) {			if(p->from.sym == s1)				prog_divq = p;			if(p->from.sym == s2)				prog_divqu = p;			if(p->from.sym == s3)				prog_modq = p;			if(p->from.sym == s4)				prog_modqu = p;			if(p->from.sym == s5)				prog_divl = p;			if(p->from.sym == s6)				prog_divlu = p;			if(p->from.sym == s7)				prog_modl = p;			if(p->from.sym == s8)				prog_modlu = p;		}	if(prog_divq == P) {		diag("undefined: %s", s1->name);		prog_divq = curtext;	}	if(prog_divqu == P) {		diag("undefined: %s", s2->name);		prog_divqu = curtext;	}	if(prog_modq == P) {		diag("undefined: %s", s3->name);		prog_modq = curtext;	}	if(prog_modqu == P) {		diag("undefined: %s", s4->name);		prog_modqu = curtext;	}	if(prog_divl == P) {		diag("undefined: %s", s5->name);		prog_divl = curtext;	}	if(prog_divlu == P) {		diag("undefined: %s", s6->name);		prog_divlu = curtext;	}	if(prog_modl == P) {		diag("undefined: %s", s7->name);		prog_modl = curtext;	}	if(prog_modlu == P) {		diag("undefined: %s", s8->name);		prog_modlu = curtext;	}}Prog *divsubr(int o){	switch(o) {	case ADIVQ:		return prog_divq;	case ADIVQU:		return prog_divqu;	case AMODQ:		return prog_modq;	case AMODQU:		return prog_modqu;	case ADIVL:		return prog_divl;	case ADIVLU:		return prog_divlu;	case AMODL:		return prog_modl;	case AMODLU:		return prog_modlu;	default:		diag("bad op %O in divsubr", o);		return prog_modlu;	}}Prog*divuconst(Prog *p, uvlong y, int num, int quot, int bits){	int logy, i, shift;	uvlong k, m, n, mult, tmp, msb;	if(num == NREG)		num = quot;	if(y == 0) {		diag("division by zero");		return p;	}	if(y == 1)		return genRRR(p, AMOVQ, num, NREG, quot);	if(num == REGTMP || quot == REGTMP)		diag("bad register in divuconst");	tmp = y;	for(logy = -1; tmp != 0; logy++)		tmp >>= 1;	msb = (1LL << (bits-1));	if((y & (y-1)) == 0)		/* power of 2 */		return genIRR(p, ASRLQ, logy, num, quot);	if(y > msb)		return genIRR(p, ACMPUGE, y, num, quot);	/* k = (-2^(bits+logy)) % y */	m = msb/y;	n = msb%y;	if(debug['d'])		Bprint(&bso, "divuconst: y=%lld msb=%lld m=%lld n=%lld\n",			y, msb, m, n);	for(i = 0; i <= logy; i++) {		m *= 2LL;		n *= 2LL;		if(n > y) {			m += 1LL;			n -= y;		}	}	if(debug['d'])		Bprint(&bso, "divuconst: y=%lld msb=%lld m=%lld n=%lld\n",			y, msb, m, n);	k = y - n;	if(k > (1LL << logy)) {		mult = 2LL*m + 1LL;		bits++;	} else		mult = m + 1LL;	shift = bits + logy;	if(debug['d'])		Bprint(&bso, "divuconst: y=%lld mult=%lld shift=%d bits=%d k=%lld\n",			y, mult, shift, bits, k);	if(bits <= 32) {		p = genIRR(p, AMOVQ, mult, NREG, REGTMP);		p = genRRR(p, AEXTLL, REGZERO, num, quot);		p = genRRR(p, AMULQ, REGTMP, quot, quot);		p = genIRR(p, ASRLQ, shift, quot, quot);		p = genRRR(p, AADDL, quot, REGZERO, quot);		return p;	}	if(bits == 33) {		if(shift < 64) {			mult <<= (64-shift);			shift = 64;		}		p = genIRR(p, AMOVQ, mult, NREG, REGTMP);		p = genRRR(p, AEXTLL, REGZERO, num, quot);		p = genRRR(p, AUMULH, REGTMP, quot, quot);		if(shift != 64)			p = genIRR(p, ASRLQ, shift-64, quot, quot);		p = genRRR(p, AADDL, quot, REGZERO, quot);		return p;	}	if(bits <= 64) {		if(shift < 64) {			mult <<= (64-shift);			shift = 64;		}		p = genIRR(p, AMOVQ, mult, NREG, REGTMP);		p = genRRR(p, AUMULH, REGTMP, num, quot);		if(shift != 64)			p = genIRR(p, ASRLQ, shift-64, quot, quot);		return p;	}	p = genIRR(p, AMOVQ, mult, NREG, REGTMP);	p = genRRR(p, AUMULH, REGTMP, num, REGTMP);	p = genRRR(p, AADDQ, num, REGTMP, quot);	p = genRRR(p, ACMPUGT, REGTMP, quot, REGTMP);	p = genIRR(p, ASLLQ, 128-shift, REGTMP, REGTMP);	p = genIRR(p, ASRLQ, shift-64, quot, quot);	p = genRRR(p, AADDQ, REGTMP, quot, quot);	return p;}Prog *divconst(Prog *p, vlong y, int num, int quot, int bits){	vlong yabs;	Prog *q;	yabs = y;	if (y < 0)		yabs = -y;	q = genRRR(p, ASUBQ, num, REGZERO, REGTMP2);	if (num != quot)		q = genRRR(q, AMOVQ, num, NREG, quot);	q = genRRR(q, ACMOVGT, REGTMP2, REGTMP2, quot);	q = divuconst(q, yabs, quot, quot, bits-1);	q = genRRR(q, ASUBQ, quot, REGZERO, REGTMP);	q = genRRR(q, (y < 0)? ACMOVLT: ACMOVGT, REGTMP, REGTMP2, quot);	return q;}Prog *modconst(Prog *p, vlong y, int num, int quot, int bits){	vlong yabs;	Prog *q;	yabs = y;	if (y < 0)		yabs = -y;	q = genRRR(p, ASUBQ, num, REGZERO, REGTMP2);	q = genRRR(q, ACMOVLT, num, REGTMP2, REGTMP2);	q = divuconst(q, yabs, REGTMP2, REGTMP2, bits-1);	q = genRRR(q, ASUBQ, REGTMP2, REGZERO, REGTMP);	q = genRRR(q, ACMOVLT, REGTMP, num, REGTMP2);	q = genIRR(q, AMULQ, yabs, REGTMP2, REGTMP2);	q = genRRR(q, ASUBQ, REGTMP2, num, quot);	return q;}Prog *genXXX(Prog *q, int op, Adr *from, int reg, Adr *to){	Prog *p;	p = prg();	p->as = op;	p->line = q->line;	p->from = *from;	p->to = *to;	p->reg = reg;	p->link = q->link;	q->link = p;	return p;}Prog *genRRR(Prog *q, int op, int from, int reg, int to){	Prog *p;	p = prg();	p->as = op;	p->line = q->line;	p->from.type = D_REG;	p->from.reg = from;	p->to.type = D_REG;	p->to.reg = to;	p->reg = reg;	p->link = q->link;	q->link = p;	return p;}Prog *genIRR(Prog *q, int op, vlong v, int reg, int to){	Prog *p;	p = prg();	p->as = op;	p->line = q->line;	p->from.type = D_CONST;	p->from.offset = v;	p->to.type = D_REG;	p->to.reg = to;	p->reg = reg;	p->link = q->link;	q->link = p;	return p;}Prog *genstore(Prog *q, int op, int from, vlong offset, int to){	Prog *p;	p = prg();	p->as = op;	p->line = q->line;	p->from.type = D_REG;	p->from.reg = from;	p->to.type = D_OREG;	p->to.reg = to;	p->to.offset = offset;	p->reg = NREG;	p->link = q->link;	q->link = p;	return p;}Prog *genload(Prog *q, int op, vlong offset, int from, int to){	Prog *p;	p = prg();	p->as = op;	p->line = q->line;	p->from.type = D_OREG;	p->from.offset = offset;	p->from.reg = from;	p->to.type = D_REG;	p->to.reg = to;	p->reg = NREG;	p->link = q->link;	q->link = p;	return p;}

⌨️ 快捷键说明

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