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

📄 noop.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"l.h"Prog	*divuconst(Prog *, uvlong, int, int, int);Prog	*divconst(Prog *, vlong, int, int, int);Prog	*modconst(Prog *, vlong, int, int, int);void	excise(Prog *);voidnoops(void){	Prog *p, *p1, *q, *q1, *q2;	int o, curframe, curbecome, maxbecome, shift;	/*	 * find leaf subroutines	 * become sizes	 * frame sizes	 * strip NOPs	 * expand RET and other macros	 * expand BECOME pseudo	 * use conditional moves where appropriate	 */	if(debug['v'])		Bprint(&bso, "%5.2f noops\n", cputime());	Bflush(&bso);	curframe = 0;	curbecome = 0;	maxbecome = 0;	curtext = 0;	q = P;	for(p = firstp; p != P; p = p->link) {		/* find out how much arg space is used in this TEXT */		if(p->to.type == D_OREG && p->to.reg == REGSP)			if(p->to.offset > curframe)				curframe = p->to.offset;		switch(p->as) {		case ATEXT:			if(curtext && curtext->from.sym) {				curtext->from.sym->frame = curframe;				curtext->from.sym->become = curbecome;				if(curbecome > maxbecome)					maxbecome = curbecome;			}			curframe = 0;			curbecome = 0;			p->mark |= LABEL|LEAF|SYNC;			if(p->link)				p->link->mark |= LABEL;			curtext = p;			break;		/* don't mess with what we don't understand */		case AWORD:		case ACALL_PAL:		/* etc. */			p->mark |= LABEL;			for(q1=p->link; q1 != P; q1 = q1->link) {				q1->mark |= LABEL;				if(q1->as != AXORNOT)		/* used as NOP in PALcode */					break;			}			break;		case ARET:			/* special form of RET is BECOME */			if(p->from.type == D_CONST)				if(p->from.offset > curbecome)					curbecome = p->from.offset;			if(p->link != P)				p->link->mark |= LABEL;			break;		case ANOP:			q1 = p->link;			q->link = q1;		/* q is non-nop */			q1->mark |= p->mark;			continue;		case AJSR:			if(curtext != P)				curtext->mark &= ~LEAF;		case ABEQ:		case ABNE:		case ABGE:		case ABGT:		case ABLE:		case ABLT:		case ABLBC:		case ABLBS:		case AFBEQ:		case AFBNE:		case AFBGE:		case AFBGT:		case AFBLE:		case AFBLT:		case AJMP:			p->mark |= BRANCH;			q1 = p->cond;			if(q1 != P) {				while(q1->as == ANOP) {					q1 = q1->link;					p->cond = q1;				}				if(!(q1->mark & LEAF)) {					if (q1->mark & LABEL)						q1->mark |= LABEL2;					else						q1->mark |= LABEL;				}			} else				p->mark |= LABEL;			q1 = p->link;			if(q1 != P) {				if (q1->mark & LABEL)					q1->mark |= LABEL2;				else					q1->mark |= LABEL;			}			else				p->mark |= LABEL;	/* ??? */			break;		case ADIVQ:		case ADIVQU:		case AMODQ:		case AMODQU:		case ADIVL:		case ADIVLU:		case AMODL:		case AMODLU:			if(p->from.type == D_CONST /*&& !debug['d']*/)				continue;			if(prog_divq == P)				initdiv();			if(curtext != P)				curtext->mark &= ~LEAF;			break;		}		q = p;	}	if(curtext && curtext->from.sym) {		curtext->from.sym->frame = curframe;		curtext->from.sym->become = curbecome;		if(curbecome > maxbecome)			maxbecome = curbecome;	}	if(debug['b'])		print("max become = %d\n", maxbecome);	xdefine("ALEFbecome", STEXT, maxbecome);	curtext = 0;	for(p = firstp; p != P; p = p->link) {		switch(p->as) {		case ATEXT:			curtext = p;			break;		case AJSR:			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {				o = maxbecome - curtext->from.sym->frame;				if(o <= 0)					break;				/* calling a become or calling a variable */				if(p->to.sym == S || p->to.sym->become) {					curtext->to.offset += o;					if(debug['b']) {						curp = p;						print("%D calling %D increase %d\n",							&curtext->from, &p->to, o);					}				}			}			break;		}	}	for(p = firstp; p != P; p = p->link) {		o = p->as;		switch(o) {		case ATEXT:			curtext = p;			autosize = p->to.offset + 8;			if(autosize <= 8)			if(curtext->mark & LEAF) {				p->to.offset = -8;				autosize = 0;			}			if (autosize & 4)				autosize += 4;			q = p;			if(autosize)				q = genIRR(p, ASUBQ, autosize, NREG, REGSP);			else if(!(curtext->mark & LEAF)) {				if(debug['v'])					Bprint(&bso, "save suppressed in: %s\n",						curtext->from.sym->name);				Bflush(&bso);				curtext->mark |= LEAF;			}			if(curtext->mark & LEAF) {				if(curtext->from.sym)					curtext->from.sym->type = SLEAF;				break;			}			genstore(q, AMOVL, REGLINK, 0LL, REGSP);			break;		case ARET:			nocache(p);			if(p->from.type == D_CONST)				goto become;			if(curtext->mark & LEAF) {				if(!autosize) {					p->as = AJMP;					p->from = zprg.from;					p->to.type = D_OREG;					p->to.offset = 0;					p->to.reg = REGLINK;					break;				}				p->as = AADDQ;				p->from.type = D_CONST;				p->from.offset = autosize;				p->to.type = D_REG;				p->to.reg = REGSP;				q = prg();				q->as = AJMP;				q->line = p->line;				q->to.type = D_OREG;				q->to.offset = 0;				q->to.reg = REGLINK;				q->mark |= BRANCH;				q->link = p->link;				p->link = q;				break;			}			p->as = AMOVL;			p->from.type = D_OREG;			p->from.offset = 0;			p->from.reg = REGSP;			p->to.type = D_REG;			p->to.reg = REGLINK;			q = p;			if(autosize)				q = genIRR(p, AADDQ, autosize, NREG, REGSP);			q1 = prg();			q1->as = AJMP;			q1->line = p->line;			q1->to.type = D_OREG;			q1->to.offset = 0;			q1->to.reg = REGLINK;			q1->mark |= BRANCH;			q1->link = q->link;			q->link = q1;			break;		become:			if(curtext->mark & LEAF) {				q = prg();				q->line = p->line;				q->as = AJMP;				q->from = zprg.from;				q->to = p->to;				q->cond = p->cond;				q->link = p->link;				q->mark |= BRANCH;				p->link = q;				p->as = AADDQ;				p->from = zprg.from;				p->from.type = D_CONST;				p->from.offset = autosize;				p->to = zprg.to;				p->to.type = D_REG;				p->to.reg = REGSP;				break;			}			q = prg();			q->line = p->line;			q->as = AJMP;			q->from = zprg.from;			q->to = p->to;			q->cond = p->cond;			q->link = p->link;			q->mark |= BRANCH;			p->link = q;			q = genIRR(p, AADDQ, autosize, NREG, REGSP);			p->as = AMOVL;			p->from = zprg.from;			p->from.type = D_OREG;			p->from.offset = 0;			p->from.reg = REGSP;			p->to = zprg.to;			p->to.type = D_REG;			p->to.reg = REGLINK;			break;					/* All I wanted was a MOVB... */		case AMOVB:		case AMOVW:			/* rewrite sign extend; could use v3 extension in asmout case 1 */			if (p->to.type == D_REG) {				nocache(p);				shift = (p->as == AMOVB) ? (64-8) : (64-16);				if (p->from.type == D_REG) {					p->as = ASLLQ;					p->reg = p->from.reg;					p->from.type = D_CONST;					p->from.offset = shift;					q = genIRR(p, ASRAQ, shift, p->to.reg, p->to.reg);					break;				}				else {					p->as = (p->as == AMOVB) ? AMOVBU : AMOVWU;					q = genIRR(p, ASLLQ, shift, p->to.reg, p->to.reg);					q = genIRR(q, ASRAQ, shift, p->to.reg, p->to.reg);				}			}			/* fall through... */		case AMOVBU:		case AMOVWU:			if(!debug['x'])				break;		/* use BWX extension */			o = p->as;			nocache(p);			if (p->from.type == D_OREG) {				if (p->to.type != D_REG)					break;				p->as = AMOVQU;				q = genXXX(p, AEXTBL, &p->to, REGTMP2, &p->to);				if (o == AMOVW || o == AMOVWU)					q->as = AEXTWL;				p->to.reg = REGTMP2;				if ((p->from.offset & 7) != 0 || aclass(&p->from) != C_SOREG) {					q1 = genXXX(p, AMOVA, &p->from, NREG, &q->to);					q1->from.offset &= 7;					q->from = q->to;				}				else					q->from.reg = p->from.reg;				if (o == AMOVB || o == AMOVW)					genXXX(q, o, &q->to, NREG, &q->to);			}			else if (p->to.type == D_OREG) {				if (aclass(&p->from) == C_ZCON) {					p->from.type = D_REG;					p->from.reg = REGZERO;				}				else if (p->from.type != D_REG)					break;				p->as = AMOVQU;				q = genRRR(p, AMSKBL, p->to.reg, REGTMP2, REGTMP2);				q1 = genRRR(q, AINSBL, p->to.reg, p->from.reg, REGTMP);				if (o == AMOVW || o == AMOVWU) {					q->as = AMSKWL;					q1->as = AINSWL;				}				q2 = genXXX(q1, AOR, &q->to, REGTMP, &q->to);				genXXX(q2, AMOVQU, &q->to, NREG, &p->to);				p->from = p->to;				p->to = q->to;				if ((p->from.offset & 7) != 0 || aclass(&p->from) != C_SOREG) {					q->from.reg = REGTMP;					q1->from.reg = REGTMP;					q = genXXX(p, AMOVA, &p->from, NREG, &q->from);					q->from.offset &= 7;				}			}			break;		case ASLLL:			p->as = ASLLQ;			p = genXXX(p, AADDL, &p->to, REGZERO, &p->to);			break;		case ASRLL:			if (p->to.type != D_REG) {				diag("illegal dest type in %P", p);				break;			}			if (p->reg == NREG)				p->reg = p->to.reg;			q = genXXX(p, ASRLQ, &p->from, REGTMP, &p->to);			p->as = AZAP;			p->from.type = D_CONST;			p->from.offset = 0xf0;			p->to.reg = REGTMP;			p = q;			p = genXXX(p, AADDL, &p->to, REGZERO, &p->to);			break;		case ASRAL:			p->as = ASRAQ;			break;		case ADIVQ:		case ADIVQU:		case AMODQ:		case AMODQU:		case ADIVL:		case ADIVLU:		case AMODL:		case AMODLU:			/* if (debug['d'])				print("%P\n", p); */			if(p->to.type != D_REG)				break;			/*if(debug['d'] && p->from.type == D_CONST) {				q = genRRR(p, p->as, REGTMP, p->reg, p->to.reg);				p->as = AMOVQ;				p->reg = NREG;				p->to.reg = REGTMP;				p = q;			}*/			if(p->from.type == D_CONST) {				if (p->reg == NREG)					p->reg = p->to.reg;				switch (p->as) {				case ADIVQ:					q = divconst(p, p->from.offset, p->reg, p->to.reg, 64);					break;				case ADIVQU:					q = divuconst(p, p->from.offset, p->reg, p->to.reg, 64);					break;				case AMODQ:					q = modconst(p, p->from.offset, p->reg, p->to.reg, 64);					break;				case AMODQU:					q = divuconst(p, p->from.offset, p->reg, REGTMP2, 64);					q = genIRR(q, AMULQ, p->from.offset, REGTMP2, REGTMP2);					q = genRRR(q, ASUBQ, REGTMP2, p->reg, p->to.reg);					break;				case ADIVL:					q = divconst(p, p->from.offset, p->reg, p->to.reg, 32);					break;				case ADIVLU:					q = divuconst(p, p->from.offset, p->reg, p->to.reg, 32);					break;				case AMODL:					q = modconst(p, p->from.offset, p->reg, p->to.reg, 32);					break;				case AMODLU:					q = divuconst(p, p->from.offset, p->reg, REGTMP2, 32);					q = genIRR(q, AMULQ, p->from.offset, REGTMP2, REGTMP2);					q = genRRR(q, ASUBQ, REGTMP2, p->reg, p->to.reg);					break;				}				excise(p);

⌨️ 快捷键说明

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