forsyth20121205-174063a80cc13 years agoHistory
650 lines · 10.9 KB · C
RawDownload
#include	"l.h" voidnoops(void){	Prog *p, *p1, *q, *q1;	int o, curframe, curbecome, maxbecome; 	/*	 * find leaf subroutines	 * become sizes	 * frame sizes	 * strip NOPs	 * expand RET	 * expand BECOME pseudo	 */ 	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) {		/* too hard, just leave alone */		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; 			q = p;			p->mark |= LABEL|LEAF|SYNC;			if(p->link)				p->link->mark |= LABEL;			curtext = p;			break; 		case AORN:			q = p;			if(p->to.type == D_REG)				if(p->to.reg == REGZERO)					p->mark |= LABEL|SYNC;			break; 		case AUNIMP:		case ATAS:		case ASWAP:		case ATA:		case ATCC:		case ATCS:		case ATE:		case ATG:		case ATGE:		case ATGU:		case ATL:		case ATLE:		case ATLEU:		case ATN:		case ATNE:		case ATNEG:		case ATPOS:		case ATVC:		case ATVS:		case AWORD:			q = p;			p->mark |= LABEL|SYNC;			continue; 		case AFABSD:		case AFABSF:		case AFABSX:		case AFADDD:		case AFADDF:		case AFADDX:		case AFDIVD:		case AFDIVF:		case AFDIVX:		case AFMOVD:		case AFMOVDF:		case AFMOVDW:		case AFMOVDX:		case AFMOVF:		case AFMOVFD:		case AFMOVFW:		case AFMOVFX:		case AFMOVWD:		case AFMOVWF:		case AFMOVWX:		case AFMOVX:		case AFMOVXD:		case AFMOVXF:		case AFMOVXW:		case AFMULD:		case AFMULF:		case AFMULX:		case AFNEGD:		case AFNEGF:		case AFNEGX:		case AFSQRTD:		case AFSQRTF:		case AFSQRTX:		case AFSUBD:		case AFSUBF:		case AFSUBX:			q = p;			p->mark |= FLOAT;			continue; 		case AMUL:		case ADIV:		case ADIVL:		case AMOD:		case AMODL:			q = p;			if(!debug['M']) {				if(prog_mul == P)					initmuldiv();				if(curtext != P)					curtext->mark &= ~LEAF;			}			continue; 		case AJMPL:			if(curtext != P)				curtext->mark &= ~LEAF; 		case AJMP: 		case ABA:		case ABN:		case ABE:		case ABNE:		case ABLE:		case ABG:		case ABL:		case ABGE:		case ABLEU:		case ABGU:		case ABCS:		case ABCC:		case ABNEG:		case ABPOS:		case ABVC:		case ABVS: 		case AFBN:		case AFBO:		case AFBE:		case AFBLG:		case AFBG:		case AFBLE:		case AFBGE:		case AFBL:		case AFBNE:		case AFBUE:		case AFBA:		case AFBU:		case AFBUG:		case AFBULE:		case AFBUGE:		case AFBUL:			p->mark |= BRANCH;			q = p;			q1 = p->cond;			if(q1 != P) {				while(q1->as == ANOP) {					q1 = q1->link;					p->cond = q1;				}				if(!(q1->mark & LEAF))					q1->mark |= LABEL;			} else				p->mark |= LABEL;			q1 = p->link;			if(q1 != P)				q1->mark |= LABEL;			continue; 		case AFCMPD:		case AFCMPED:		case AFCMPEF:		case AFCMPEX:		case AFCMPF:		case AFCMPX:			q = p;			p->mark |= FCMP|FLOAT;			continue; 		case ARETURN:			/* special form of RETURN is BECOME */			if(p->from.type == D_CONST)				if(p->from.offset > curbecome)					curbecome = p->from.offset; 			q = p;			if(p->link != P)				p->link->mark |= LABEL;			continue; 		case ANOP:			q1 = p->link;			q->link = q1;		/* q is non-nop */			q1->mark |= p->mark;			continue; 		default:			q = p;			continue;		}	}	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 AJMPL:			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;		}	} 	curtext = P;	for(p = firstp; p != P; p = p->link) {		o = p->as;		switch(o) {		case ATEXT:			curtext = p;			autosize = p->to.offset + 4;			if((p->mark & LEAF) && autosize <= 4)				autosize = 0;			else				if(autosize & 4)					autosize += 4;			p->to.offset = autosize - 4; 			q = p;			if(autosize) {				q = prg();				q->as = ASUB;				q->line = p->line;				q->from.type = D_CONST;				q->from.offset = autosize;				q->to.type = D_REG;				q->to.reg = REGSP; 				q->link = p->link;				p->link = q;			} else			if(!(curtext->mark & LEAF)) {				if(debug['v'])					Bprint(&bso, "save suppressed in: %s\n",						curtext->from.sym->name);				curtext->mark |= LEAF;			} 			if(curtext->mark & LEAF) {				if(curtext->from.sym)					curtext->from.sym->type = SLEAF;				break;			} 			q1 = prg();			q1->as = AMOVW;			q1->line = p->line;			q1->from.type = D_REG;			q1->from.reg = REGLINK;			q1->to.type = D_OREG;			q1->from.offset = 0;			q1->to.reg = REGSP; 			q1->link = q->link;			q->link = q1;			break; 		case AMUL:		case ADIV:		case ADIVL:		case AMOD:		case AMODL:			if(debug['M'])				break;			if(p->from.type != D_REG)				break;			if(p->to.type != D_REG)				break;			q1 = p; 			/* MOV a,4(SP) */			q = prg();			q->link = p->link;			p->link = q;			p = q; 			p->as = AMOVW;			p->line = q1->line;			p->from.type = D_REG;			p->from.reg = q1->from.reg;			p->to.type = D_OREG;			p->to.reg = REGSP;			p->to.offset = 4; 			/* MOV b,REGTMP */			q = prg();			q->link = p->link;			p->link = q;			p = q; 			p->as = AMOVW;			p->line = q1->line;			p->from.type = D_REG;			p->from.reg = q1->reg;			if(q1->reg == NREG)				p->from.reg = q1->to.reg;			p->to.type = D_REG;			p->to.reg = REGTMP;			p->to.offset = 0; 			/* CALL appropriate */			q = prg();			q->link = p->link;			p->link = q;			p = q; 			p->as = AJMPL;			p->line = q1->line;			p->to.type = D_BRANCH;			p->cond = p;			p->mark |= BRANCH;			switch(o) {			case AMUL:				p->cond = prog_mul;				break;			case ADIV:				p->cond = prog_div;				break;			case ADIVL:				p->cond = prog_divl;				break;			case AMOD:				p->cond = prog_mod;				break;			case AMODL:				p->cond = prog_modl;				break;			} 			/* MOV REGTMP, b */			q = prg();			q->link = p->link;			p->link = q;			p = q; 			p->as = AMOVW;			p->line = q1->line;			p->from.type = D_REG;			p->from.reg = REGTMP;			p->from.offset = 0;			p->to.type = D_REG;			p->to.reg = q1->to.reg; 			/* ADD $8,SP */			q = prg();			q->link = p->link;			p->link = q;			p = q; 			p->as = AADD;			p->from.type = D_CONST;			p->from.reg = NREG;			p->from.offset = 8;			p->reg = NREG;			p->to.type = D_REG;			p->to.reg = REGSP; 			/* SUB $8,SP */			q1->as = ASUB;			q1->from.type = D_CONST;			q1->from.offset = 8;			q1->from.reg = NREG;			q1->reg = NREG;			q1->to.type = D_REG;			q1->to.reg = REGSP;			break; 		case ARETURN:			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 = 8;					p->to.reg = REGLINK;					p->mark |= BRANCH;					break;				} 				p->as = AADD;				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 = 8;				q->to.reg = REGLINK;				q->mark |= BRANCH; 				q->link = p->link;				p->link = q;				break;			} 			p->as = AMOVW;			p->from.type = D_OREG;			p->from.offset = 0;			p->from.reg = REGSP;			p->to.type = D_REG;			p->to.reg = REGRET+1; 			q = p;			if(autosize) {				q = prg();				q->as = AADD;				q->line = p->line;				q->from.type = D_CONST;				q->from.offset = autosize;				q->to.type = D_REG;				q->to.reg = REGSP; 				q->link = p->link;				p->link = q;			} 			q1 = prg();			q1->as = AJMP;			q1->line = p->line;			q1->to.type = D_OREG;			q1->to.offset = 8;			q1->to.reg = REGRET+1;			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;

Lines 1–500 of 650.