forsyth20121205-174063a80cc13 years agoHistory
1073 lines · 15.5 KB · C
RawDownload
#include "gc.h" voidpeep(void){	Reg *r, *r1, *r2;	Prog *p, *p1;	int t, s;/* * complete R structure */	t = 0;	for(r=firstr; r!=R; r=r1) {		r1 = r->link;		if(r1 == R)			break;		p = r->prog->link;		while(p != r1->prog)		switch(p->as) {		default:			r2 = rega();			r->link = r2;			r2->link = r1; 			r2->prog = p;			r2->p1 = r;			r->s1 = r2;			r2->s1 = r1;			r1->p1 = r2; 			r = r2;			t++; 		case ADATA:		case AGLOBL:		case ANAME:		case ASIGNAME:			p = p->link;		}	} loop1:	/*	 * propigate move's by renaming	 */	t = 0;	for(r=firstr; r!=R; r=r->link) {		p = r->prog;		if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED)		if(regtyp(p->from.type))		if(anyvar(&p->to)) {			if(copyprop(r)) {				excise(r);				t++;			} else			if(subprop(r) && copyprop(r)) {				excise(r);				t++;			}		}	}	if(t)		goto loop1;	for(r=firstr; r!=R; r=r->link) {		p = r->prog;		/*		 * convert (A) ... A++ into (A)++		 * and     A-- ... (A) into --(A)		 */		t = aregind(&p->from);		if(t == D_NONE)			goto out1;		s = asize(p->as);		if(s == 0)			goto out1;		r1 = findop(r, t, AADDL, s);		if(r1 != R) {			if(usedin(t, &p->to))				goto out1;			p->from.type += I_INDINC - I_INDIR;			excise(r1);			goto out1;		}		r1 = findop(r, t, ASUBL, s);		if(r1 != R) {			p->from.type += I_INDDEC - I_INDIR;			excise(r1);		}	out1:		t = aregind(&p->to);		if(t == D_NONE)			goto out2;		s = asize(p->as);		if(s == 0)			goto out2;		r1 = findop(r, t, AADDL, s);		if(r1 != R) {			p->to.type += I_INDINC - I_INDIR;			excise(r1);			goto out2;		}		r1 = findop(r, t, ASUBL, s);		if(r1 != R) {			if(usedin(t, &p->from))				goto out2;			p->to.type += I_INDDEC - I_INDIR;			excise(r1);		}	out2:		/*		 * get rid of unneeded save/restore CCR		 */		if(p->from.type == D_CCR) {			r1 = findccr(r);			if(r1 != R) {				excise(r);				excise(r1);			}		}		switch(p->as) {		case ATSTB:		case ATSTW:		case ATSTL:			if(findtst(r, r->prog, 0))				excise(r);		}		/*		 * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP		 */		if(p->as == ATSTB && (r1 = r->s1)) {			if((r1->prog->as == ABLT && (r2 = r1->s1)) ||			   (r1->prog->as == ABGE && (r2 = r1->s2))) {				p1 = r2->prog;				if(p1->as == AORB)				if(p1->from.type == D_CONST)				if(p1->from.offset == 128)				if(r1 == uniqp(r2))				if(tasas(&p->to, &p1->to)) {					p->as = ATAS;					excise(r2);				}			}		}	}} voidexcise(Reg *r){ 	p = r->prog;	p->as = ANOP;	p->from = zprog.from;	p->to = zprog.to;} Reg*uniqp(Reg *r){	Reg *r1; 	r1 = r->p1;	if(r1 == R) {		r1 = r->p2;		if(r1 == R || r1->p2link != R)			return R;	} else		if(r->p2 != R)			return R;	return r1;} Reg*uniqs(Reg *r){	Reg *r1; 	r1 = r->s1;	if(r1 == R) {		r1 = r->s2;		if(r1 == R)			return R;	} else		if(r->s2 != R)			return R;	return r1;} /* * chase backward all cc setting. * returns 1 if all set same. */intfindtst(Reg *r0, Prog *rp, int n){	Reg *r;	int c; loop:	n++;	if(n >= 10)		return 0;	for(r=r0->p2; r!=R; r=r->p2link) {		c = setcc(r->prog, rp);		if(c > 0)			continue;		if(c == 0)			return 0;		if(findtst(r, rp, n) == 0)			return 0;	}	r = r0->p1;	if(r == R)		return 1;	c = setcc(r->prog, rp);	if(c > 0)		return 1;	if(c == 0)		return 0;	r0 = r;	goto loop;} /* * tests cc * returns -1 if no change * returns 1 if set the same * returns 0 if set different */intsetcc(Prog *p, Prog *rp){	int s; 	s = asize(rp->as);	switch(p->as) {	default:		if(debug['P'])			print("unknown setcc %A\n", p->as);		break; 	case ACMPB:	case ACMPW:	case ACMPL:	case ABSR:		return 0; 	case ABRA:	case ABGE:	case ABNE:	case ABLE:	case ABEQ:	case ABHI:	case ABLS:	case ABMI:	case ABPL:	case ABGT:	case ABLT:	case ABCC:	case ABCS:	case APEA:	case ALEA:	case ANOP: 	case AFADDD:	case AFMULD:	case AFDIVD:	case AFSUBD:	case AFADDF:	case AFMULF:	case AFDIVF:	case AFSUBF:	case AADJSP:		return -1; 	case AADDW:	case AADDL:	case ASUBW:	case ASUBL:	case ACLRL:	case ACLRW:		if(p->to.type >= D_A0 && p->to.type < D_A0+8)			goto areg; 	case AADDB:	case ASUBB:	case AANDB:	case AANDW:	case AANDL:	case AORB:	case AORW:	case AORL:	case AEORB:	case AEORW:	case AEORL:	case ALSLB:	case ALSLW:	case ALSLL:	case ALSRB:	case ALSRW:	case ALSRL:	case AASLB:	case AASLW:	case AASLL:	case AASRB:	case AASRW:	case AASRL:	case ATSTB:	case ATSTW:	case ATSTL:	case ANEGB:	case ANEGW:	case ANEGL:	case ACLRB:		if(asize(p->as) != s)			break;		if(compat(&rp->to, &p->to))			return 1;		break; 	case AMOVW:	case AMOVL:		if(p->to.type >= D_A0 && p->to.type < D_A0+8)			goto areg;	case AMOVB:		if(asize(p->as) != s)			break;		if(compat(&rp->to, &p->to))			return 1;		if(compat(&rp->to, &p->from))			return 1;	}	return 0; areg:	if((rp->to.type&D_MASK) == p->to.type)		return 0;	return -1;} intcompat(Adr *a, Adr *b){	int o; 	if(a->index != D_NONE)		return 0;	if(b->index != D_NONE)		return 0;	o = a->type;	if((o >= D_R0 && o < D_R0+NREG) ||	   (o >= D_A0 && o < D_A0+NREG))		return o == b->type;	o &= D_MASK;	if(o >= D_A0 && o < D_A0+NREG) {		if(o != (b->type&D_MASK))			return 0;		if(a->offset != b->offset)			return 0;		o = a->type & I_MASK;		if(o == I_INDIR) {			o = b->type & I_MASK;			if(o == I_INDIR || o == I_INDDEC)				return 1;			return 0;		}		if(o == I_INDINC) {			o = b->type & I_MASK;			if(o == I_INDIR) {				b->type += I_INDINC-I_INDIR;				return 1;			}			if(o == I_INDDEC) {				b->type += I_INDIR-I_INDDEC;				return 1;			}			return 0;		}	}	return 0;} intaregind(Adr *a){	int t; 	t = a->type;	if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR))	while(a->offset == 0 && a->index == D_NONE)		return t & D_MASK;	return D_NONE;} intasize(int a){ 	switch(a) {	case AFTSTD:	case AFMOVED:	case AFADDD:	case AFSUBD:	case AFMULD:	case AFDIVD:	case AFCMPD:	case AFNEGD:		return 8; 	case AFTSTF:	case AFMOVEF:	case AFADDF:	case AFSUBF:	case AFMULF:	case AFDIVF:	case AFCMPF:	case AFNEGF: 	case ACLRL:	case ATSTL:	case AMOVL:	case AADDL:	case ASUBL:	case ACMPL:	case AANDL:	case AORL:	case AEORL:	case ALSLL:	case ALSRL:	case AASLL:	case AASRL:	case ANEGL:		return 4; 	case ACLRW:	case ATSTW:	case AMOVW:	case AADDW:	case ASUBW:	case ACMPW:	case AANDW:	case AORW:	case AEORW:	case ALSLW:	case ALSRW:	case AASLW:	case AASRW:	case ANEGW:		return 2; 	case ACLRB:	case ATSTB:	case AMOVB:	case AADDB:	case ASUBB:	case ACMPB:	case AANDB:	case AORB:	case AEORB:	case ALSLB:	case ALSRB:	case AASLB:	case AASRB:	case ANEGB:		return 1;	}	if(debug['P'])		print("unknown asize %A\n", p->as);	return 0;} intusedin(int t, Adr *a){ 	if((a->type&D_MASK) == t)		return 1;	if((a->index&D_MASK) == t)		return 1;	return 0;} Reg*findccr(Reg *r){	Prog *p; 	for(;;) {		r = uniqs(r);		if(r == R)			break;		p = r->prog;		if(p->to.type == D_CCR)			return r;		if(setccr(p))			break;	}	return R;} 

Lines 1–500 of 1073.