xref: /inferno-os/utils/tc/peep.c (revision d67b7dad77bb8aa973dad1f7c3ab0c309b114278)
174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth void
peep(void)474a4d8c2SCharles.Forsyth peep(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 	Reg *r, *r1, *r2;
774a4d8c2SCharles.Forsyth 	Prog *p, *p1;
874a4d8c2SCharles.Forsyth 	int t;
974a4d8c2SCharles.Forsyth /*
1074a4d8c2SCharles.Forsyth  * complete R structure
1174a4d8c2SCharles.Forsyth  */
1274a4d8c2SCharles.Forsyth 	t = 0;
1374a4d8c2SCharles.Forsyth 	for(r=firstr; r!=R; r=r1) {
1474a4d8c2SCharles.Forsyth 		r1 = r->link;
1574a4d8c2SCharles.Forsyth 		if(r1 == R)
1674a4d8c2SCharles.Forsyth 			break;
1774a4d8c2SCharles.Forsyth 		p = r->prog->link;
1874a4d8c2SCharles.Forsyth 		while(p != r1->prog)
1974a4d8c2SCharles.Forsyth 		switch(p->as) {
2074a4d8c2SCharles.Forsyth 		default:
2174a4d8c2SCharles.Forsyth 			r2 = rega();
2274a4d8c2SCharles.Forsyth 			r->link = r2;
2374a4d8c2SCharles.Forsyth 			r2->link = r1;
2474a4d8c2SCharles.Forsyth 
2574a4d8c2SCharles.Forsyth 			r2->prog = p;
2674a4d8c2SCharles.Forsyth 			r2->p1 = r;
2774a4d8c2SCharles.Forsyth 			r->s1 = r2;
2874a4d8c2SCharles.Forsyth 			r2->s1 = r1;
2974a4d8c2SCharles.Forsyth 			r1->p1 = r2;
3074a4d8c2SCharles.Forsyth 
3174a4d8c2SCharles.Forsyth 			r = r2;
3274a4d8c2SCharles.Forsyth 			t++;
3374a4d8c2SCharles.Forsyth 
3474a4d8c2SCharles.Forsyth 		case ADATA:
3574a4d8c2SCharles.Forsyth 		case AGLOBL:
3674a4d8c2SCharles.Forsyth 		case ANAME:
3774a4d8c2SCharles.Forsyth 		case ASIGNAME:
3874a4d8c2SCharles.Forsyth 			p = p->link;
3974a4d8c2SCharles.Forsyth 		}
4074a4d8c2SCharles.Forsyth 	}
4174a4d8c2SCharles.Forsyth 
4274a4d8c2SCharles.Forsyth loop1:
4374a4d8c2SCharles.Forsyth 	t = 0;
4474a4d8c2SCharles.Forsyth 	for(r=firstr; r!=R; r=r->link) {
4574a4d8c2SCharles.Forsyth 		p = r->prog;
4674a4d8c2SCharles.Forsyth 		if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD)
4774a4d8c2SCharles.Forsyth 		if(regtyp(&p->to)) {
4874a4d8c2SCharles.Forsyth 			if(p->from.type == D_CONST)
4974a4d8c2SCharles.Forsyth 				constprop(&p->from, &p->to, r->s1);
5074a4d8c2SCharles.Forsyth 			else if(regtyp(&p->from))
5174a4d8c2SCharles.Forsyth 			if(p->from.type == p->to.type) {
5274a4d8c2SCharles.Forsyth 				if(copyprop(r)) {
5374a4d8c2SCharles.Forsyth 					excise(r);
5474a4d8c2SCharles.Forsyth 					t++;
5574a4d8c2SCharles.Forsyth 				} else
5674a4d8c2SCharles.Forsyth 				if(subprop(r) && copyprop(r)) {
5774a4d8c2SCharles.Forsyth 					excise(r);
5874a4d8c2SCharles.Forsyth 					t++;
5974a4d8c2SCharles.Forsyth 				}
6074a4d8c2SCharles.Forsyth 			}
6174a4d8c2SCharles.Forsyth 		}
6274a4d8c2SCharles.Forsyth 	}
6374a4d8c2SCharles.Forsyth 	if(t)
6474a4d8c2SCharles.Forsyth 		goto loop1;
6574a4d8c2SCharles.Forsyth 	/*
6674a4d8c2SCharles.Forsyth 	 * look for MOVB x,R; MOVB R,R
6774a4d8c2SCharles.Forsyth 	 */
6874a4d8c2SCharles.Forsyth 	for(r=firstr; r!=R; r=r->link) {
6974a4d8c2SCharles.Forsyth 		p = r->prog;
7074a4d8c2SCharles.Forsyth 		switch(p->as) {
7174a4d8c2SCharles.Forsyth 		default:
7274a4d8c2SCharles.Forsyth 			continue;
7374a4d8c2SCharles.Forsyth 		case AEOR:
7474a4d8c2SCharles.Forsyth 			/*
7574a4d8c2SCharles.Forsyth 			 * EOR -1,x,y => MVN x,y
7674a4d8c2SCharles.Forsyth 			 */
7774a4d8c2SCharles.Forsyth 			if(p->from.type == D_CONST && p->from.offset == -1) {
7874a4d8c2SCharles.Forsyth 				p->as = AMVN;
7974a4d8c2SCharles.Forsyth 				p->from.type = D_REG;
8074a4d8c2SCharles.Forsyth 				if(p->reg != NREG)
8174a4d8c2SCharles.Forsyth 					p->from.reg = p->reg;
8274a4d8c2SCharles.Forsyth 				else
8374a4d8c2SCharles.Forsyth 					p->from.reg = p->to.reg;
8474a4d8c2SCharles.Forsyth 				p->reg = NREG;
8574a4d8c2SCharles.Forsyth 			}
8674a4d8c2SCharles.Forsyth 			continue;
8774a4d8c2SCharles.Forsyth 		case AMOVH:
8874a4d8c2SCharles.Forsyth 		case AMOVHU:
8974a4d8c2SCharles.Forsyth 		case AMOVB:
9074a4d8c2SCharles.Forsyth 		case AMOVBU:
9174a4d8c2SCharles.Forsyth 			if(p->to.type != D_REG)
9274a4d8c2SCharles.Forsyth 				continue;
9374a4d8c2SCharles.Forsyth 			break;
9474a4d8c2SCharles.Forsyth 		}
9574a4d8c2SCharles.Forsyth 		r1 = r->link;
9674a4d8c2SCharles.Forsyth 		if(r1 == R)
9774a4d8c2SCharles.Forsyth 			continue;
9874a4d8c2SCharles.Forsyth 		p1 = r1->prog;
9974a4d8c2SCharles.Forsyth 		if(p1->as != p->as)
10074a4d8c2SCharles.Forsyth 			continue;
10174a4d8c2SCharles.Forsyth 		if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
10274a4d8c2SCharles.Forsyth 			continue;
10374a4d8c2SCharles.Forsyth 		if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
10474a4d8c2SCharles.Forsyth 			continue;
10574a4d8c2SCharles.Forsyth 		excise(r1);
10674a4d8c2SCharles.Forsyth 	}
10774a4d8c2SCharles.Forsyth }
10874a4d8c2SCharles.Forsyth 
10974a4d8c2SCharles.Forsyth void
excise(Reg * r)11074a4d8c2SCharles.Forsyth excise(Reg *r)
11174a4d8c2SCharles.Forsyth {
11274a4d8c2SCharles.Forsyth 	Prog *p;
11374a4d8c2SCharles.Forsyth 
11474a4d8c2SCharles.Forsyth 	p = r->prog;
11574a4d8c2SCharles.Forsyth 	p->as = ANOP;
11674a4d8c2SCharles.Forsyth 	p->from = zprog.from;
11774a4d8c2SCharles.Forsyth 	p->to = zprog.to;
11874a4d8c2SCharles.Forsyth 	p->reg = zprog.reg; /**/
11974a4d8c2SCharles.Forsyth }
12074a4d8c2SCharles.Forsyth 
12174a4d8c2SCharles.Forsyth Reg*
uniqp(Reg * r)12274a4d8c2SCharles.Forsyth uniqp(Reg *r)
12374a4d8c2SCharles.Forsyth {
12474a4d8c2SCharles.Forsyth 	Reg *r1;
12574a4d8c2SCharles.Forsyth 
12674a4d8c2SCharles.Forsyth 	r1 = r->p1;
12774a4d8c2SCharles.Forsyth 	if(r1 == R) {
12874a4d8c2SCharles.Forsyth 		r1 = r->p2;
12974a4d8c2SCharles.Forsyth 		if(r1 == R || r1->p2link != R)
13074a4d8c2SCharles.Forsyth 			return R;
13174a4d8c2SCharles.Forsyth 	} else
13274a4d8c2SCharles.Forsyth 		if(r->p2 != R)
13374a4d8c2SCharles.Forsyth 			return R;
13474a4d8c2SCharles.Forsyth 	return r1;
13574a4d8c2SCharles.Forsyth }
13674a4d8c2SCharles.Forsyth 
13774a4d8c2SCharles.Forsyth Reg*
uniqs(Reg * r)13874a4d8c2SCharles.Forsyth uniqs(Reg *r)
13974a4d8c2SCharles.Forsyth {
14074a4d8c2SCharles.Forsyth 	Reg *r1;
14174a4d8c2SCharles.Forsyth 
14274a4d8c2SCharles.Forsyth 	r1 = r->s1;
14374a4d8c2SCharles.Forsyth 	if(r1 == R) {
14474a4d8c2SCharles.Forsyth 		r1 = r->s2;
14574a4d8c2SCharles.Forsyth 		if(r1 == R)
14674a4d8c2SCharles.Forsyth 			return R;
14774a4d8c2SCharles.Forsyth 	} else
14874a4d8c2SCharles.Forsyth 		if(r->s2 != R)
14974a4d8c2SCharles.Forsyth 			return R;
15074a4d8c2SCharles.Forsyth 	return r1;
15174a4d8c2SCharles.Forsyth }
15274a4d8c2SCharles.Forsyth 
15374a4d8c2SCharles.Forsyth int
regtyp(Adr * a)15474a4d8c2SCharles.Forsyth regtyp(Adr *a)
15574a4d8c2SCharles.Forsyth {
15674a4d8c2SCharles.Forsyth 
15774a4d8c2SCharles.Forsyth 	if(a->type == D_REG)
15874a4d8c2SCharles.Forsyth 		return 1;
15974a4d8c2SCharles.Forsyth 	if(a->type == D_FREG)
16074a4d8c2SCharles.Forsyth 		return 1;
16174a4d8c2SCharles.Forsyth 	return 0;
16274a4d8c2SCharles.Forsyth }
16374a4d8c2SCharles.Forsyth 
16474a4d8c2SCharles.Forsyth /*
16574a4d8c2SCharles.Forsyth  * the idea is to substitute
16674a4d8c2SCharles.Forsyth  * one register for another
16774a4d8c2SCharles.Forsyth  * from one MOV to another
16874a4d8c2SCharles.Forsyth  *	MOV	a, R0
16974a4d8c2SCharles.Forsyth  *	ADD	b, R0	/ no use of R1
17074a4d8c2SCharles.Forsyth  *	MOV	R0, R1
17174a4d8c2SCharles.Forsyth  * would be converted to
17274a4d8c2SCharles.Forsyth  *	MOV	a, R1
17374a4d8c2SCharles.Forsyth  *	ADD	b, R1
17474a4d8c2SCharles.Forsyth  *	MOV	R1, R0
17574a4d8c2SCharles.Forsyth  * hopefully, then the former or latter MOV
17674a4d8c2SCharles.Forsyth  * will be eliminated by copy propagation.
17774a4d8c2SCharles.Forsyth  */
17874a4d8c2SCharles.Forsyth int
subprop(Reg * r0)17974a4d8c2SCharles.Forsyth subprop(Reg *r0)
18074a4d8c2SCharles.Forsyth {
18174a4d8c2SCharles.Forsyth 	Prog *p;
18274a4d8c2SCharles.Forsyth 	Adr *v1, *v2;
18374a4d8c2SCharles.Forsyth 	Reg *r;
18474a4d8c2SCharles.Forsyth 	int t;
18574a4d8c2SCharles.Forsyth 
18674a4d8c2SCharles.Forsyth 	p = r0->prog;
18774a4d8c2SCharles.Forsyth 	v1 = &p->from;
18874a4d8c2SCharles.Forsyth 	if(!regtyp(v1))
18974a4d8c2SCharles.Forsyth 		return 0;
19074a4d8c2SCharles.Forsyth 	v2 = &p->to;
19174a4d8c2SCharles.Forsyth 	if(!regtyp(v2))
19274a4d8c2SCharles.Forsyth 		return 0;
19374a4d8c2SCharles.Forsyth 	for(r=uniqp(r0); r!=R; r=uniqp(r)) {
19474a4d8c2SCharles.Forsyth 		if(uniqs(r) == R)
19574a4d8c2SCharles.Forsyth 			break;
19674a4d8c2SCharles.Forsyth 		p = r->prog;
19774a4d8c2SCharles.Forsyth 		switch(p->as) {
19874a4d8c2SCharles.Forsyth 		case ABL:
19974a4d8c2SCharles.Forsyth 		case ABX:
20074a4d8c2SCharles.Forsyth 			return 0;
20174a4d8c2SCharles.Forsyth 
20274a4d8c2SCharles.Forsyth 		// case ACMP:
20374a4d8c2SCharles.Forsyth 		// case ACMN:
20474a4d8c2SCharles.Forsyth 		case AADD:
20574a4d8c2SCharles.Forsyth 		case ASUB:
20674a4d8c2SCharles.Forsyth 		// case ASLL:
20774a4d8c2SCharles.Forsyth 		// case ASRL:
20874a4d8c2SCharles.Forsyth 		// case ASRA:
20974a4d8c2SCharles.Forsyth 		// case AORR:
21074a4d8c2SCharles.Forsyth 		// case AAND:
21174a4d8c2SCharles.Forsyth 		// case AEOR:
21274a4d8c2SCharles.Forsyth 		// case AMUL:
21374a4d8c2SCharles.Forsyth 		// case ADIV:
21474a4d8c2SCharles.Forsyth 		// case ADIVU:
21574a4d8c2SCharles.Forsyth 
21674a4d8c2SCharles.Forsyth 		// case ACMPF:
21774a4d8c2SCharles.Forsyth 		// case ACMPD:
21874a4d8c2SCharles.Forsyth 		// case AADDD:
21974a4d8c2SCharles.Forsyth 		// case AADDF:
22074a4d8c2SCharles.Forsyth 		// case ASUBD:
22174a4d8c2SCharles.Forsyth 		// case ASUBF:
22274a4d8c2SCharles.Forsyth 		// case AMULD:
22374a4d8c2SCharles.Forsyth 		// case AMULF:
22474a4d8c2SCharles.Forsyth 		// case ADIVD:
22574a4d8c2SCharles.Forsyth 		// case ADIVF:
22674a4d8c2SCharles.Forsyth 			if(p->to.type == v1->type)
22774a4d8c2SCharles.Forsyth 			if(p->to.reg == v1->reg) {
22874a4d8c2SCharles.Forsyth 				if(p->reg == NREG)
22974a4d8c2SCharles.Forsyth 					p->reg = p->to.reg;
23074a4d8c2SCharles.Forsyth 				goto gotit;
23174a4d8c2SCharles.Forsyth 			}
23274a4d8c2SCharles.Forsyth 			break;
23374a4d8c2SCharles.Forsyth 
23474a4d8c2SCharles.Forsyth 		case AMOVF:
23574a4d8c2SCharles.Forsyth 		case AMOVD:
23674a4d8c2SCharles.Forsyth 		case AMOVW:
23774a4d8c2SCharles.Forsyth 			if(p->to.type == v1->type)
23874a4d8c2SCharles.Forsyth 			if(p->to.reg == v1->reg)
23974a4d8c2SCharles.Forsyth 				goto gotit;
24074a4d8c2SCharles.Forsyth 			break;
24174a4d8c2SCharles.Forsyth 
24274a4d8c2SCharles.Forsyth 		case AMOVM:
24374a4d8c2SCharles.Forsyth 			t = 1<<v2->reg;
24474a4d8c2SCharles.Forsyth 			if((p->from.type == D_CONST && (p->from.offset&t)) ||
24574a4d8c2SCharles.Forsyth 			   (p->to.type == D_CONST && (p->to.offset&t)))
24674a4d8c2SCharles.Forsyth 				return 0;
24774a4d8c2SCharles.Forsyth 			break;
24874a4d8c2SCharles.Forsyth 		}
24974a4d8c2SCharles.Forsyth 		if(copyau(&p->from, v2) ||
25074a4d8c2SCharles.Forsyth 		   copyau1(p, v2) ||
25174a4d8c2SCharles.Forsyth 		   copyau(&p->to, v2))
25274a4d8c2SCharles.Forsyth 			break;
25374a4d8c2SCharles.Forsyth 		if(copysub(&p->from, v1, v2, 0) ||
25474a4d8c2SCharles.Forsyth 		   copysub1(p, v1, v2, 0) ||
25574a4d8c2SCharles.Forsyth 		   copysub(&p->to, v1, v2, 0))
25674a4d8c2SCharles.Forsyth 			break;
25774a4d8c2SCharles.Forsyth 	}
25874a4d8c2SCharles.Forsyth 	return 0;
25974a4d8c2SCharles.Forsyth 
26074a4d8c2SCharles.Forsyth gotit:
26174a4d8c2SCharles.Forsyth 	copysub(&p->to, v1, v2, 1);
26274a4d8c2SCharles.Forsyth 	if(debug['P']) {
26374a4d8c2SCharles.Forsyth 		print("gotit: %D->%D\n%P", v1, v2, r->prog);
26474a4d8c2SCharles.Forsyth 		if(p->from.type == v2->type)
26574a4d8c2SCharles.Forsyth 			print(" excise");
26674a4d8c2SCharles.Forsyth 		print("\n");
26774a4d8c2SCharles.Forsyth 	}
26874a4d8c2SCharles.Forsyth 	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
26974a4d8c2SCharles.Forsyth 		p = r->prog;
27074a4d8c2SCharles.Forsyth 		copysub(&p->from, v1, v2, 1);
27174a4d8c2SCharles.Forsyth 		copysub1(p, v1, v2, 1);
27274a4d8c2SCharles.Forsyth 		copysub(&p->to, v1, v2, 1);
27374a4d8c2SCharles.Forsyth 		if(debug['P'])
27474a4d8c2SCharles.Forsyth 			print("%P\n", r->prog);
27574a4d8c2SCharles.Forsyth 	}
27674a4d8c2SCharles.Forsyth 	t = v1->reg;
27774a4d8c2SCharles.Forsyth 	v1->reg = v2->reg;
27874a4d8c2SCharles.Forsyth 	v2->reg = t;
27974a4d8c2SCharles.Forsyth 	if(debug['P'])
28074a4d8c2SCharles.Forsyth 		print("%P last\n", r->prog);
28174a4d8c2SCharles.Forsyth 	return 1;
28274a4d8c2SCharles.Forsyth }
28374a4d8c2SCharles.Forsyth 
28474a4d8c2SCharles.Forsyth /*
28574a4d8c2SCharles.Forsyth  * The idea is to remove redundant copies.
28674a4d8c2SCharles.Forsyth  *	v1->v2	F=0
28774a4d8c2SCharles.Forsyth  *	(use v2	s/v2/v1/)*
28874a4d8c2SCharles.Forsyth  *	set v1	F=1
28974a4d8c2SCharles.Forsyth  *	use v2	return fail
29074a4d8c2SCharles.Forsyth  *	-----------------
29174a4d8c2SCharles.Forsyth  *	v1->v2	F=0
29274a4d8c2SCharles.Forsyth  *	(use v2	s/v2/v1/)*
29374a4d8c2SCharles.Forsyth  *	set v1	F=1
29474a4d8c2SCharles.Forsyth  *	set v2	return success
29574a4d8c2SCharles.Forsyth  */
29674a4d8c2SCharles.Forsyth int
copyprop(Reg * r0)29774a4d8c2SCharles.Forsyth copyprop(Reg *r0)
29874a4d8c2SCharles.Forsyth {
29974a4d8c2SCharles.Forsyth 	Prog *p;
30074a4d8c2SCharles.Forsyth 	Adr *v1, *v2;
30174a4d8c2SCharles.Forsyth 	Reg *r;
30274a4d8c2SCharles.Forsyth 
30374a4d8c2SCharles.Forsyth 	p = r0->prog;
30474a4d8c2SCharles.Forsyth 	v1 = &p->from;
30574a4d8c2SCharles.Forsyth 	v2 = &p->to;
30674a4d8c2SCharles.Forsyth 	if(copyas(v1, v2))
30774a4d8c2SCharles.Forsyth 		return 1;
30874a4d8c2SCharles.Forsyth 	for(r=firstr; r!=R; r=r->link)
30974a4d8c2SCharles.Forsyth 		r->active = 0;
31074a4d8c2SCharles.Forsyth 	return copy1(v1, v2, r0->s1, 0);
31174a4d8c2SCharles.Forsyth }
31274a4d8c2SCharles.Forsyth 
31374a4d8c2SCharles.Forsyth int
copy1(Adr * v1,Adr * v2,Reg * r,int f)31474a4d8c2SCharles.Forsyth copy1(Adr *v1, Adr *v2, Reg *r, int f)
31574a4d8c2SCharles.Forsyth {
31674a4d8c2SCharles.Forsyth 	int t;
31774a4d8c2SCharles.Forsyth 	Prog *p;
31874a4d8c2SCharles.Forsyth 
31974a4d8c2SCharles.Forsyth 	if(r->active) {
32074a4d8c2SCharles.Forsyth 		if(debug['P'])
32174a4d8c2SCharles.Forsyth 			print("act set; return 1\n");
32274a4d8c2SCharles.Forsyth 		return 1;
32374a4d8c2SCharles.Forsyth 	}
32474a4d8c2SCharles.Forsyth 	r->active = 1;
32574a4d8c2SCharles.Forsyth 	if(debug['P'])
32674a4d8c2SCharles.Forsyth 		print("copy %D->%D f=%d\n", v1, v2, f);
32774a4d8c2SCharles.Forsyth 	for(; r != R; r = r->s1) {
32874a4d8c2SCharles.Forsyth 		p = r->prog;
32974a4d8c2SCharles.Forsyth 		if(debug['P'])
33074a4d8c2SCharles.Forsyth 			print("%P", p);
33174a4d8c2SCharles.Forsyth 		if(!f && uniqp(r) == R) {
33274a4d8c2SCharles.Forsyth 			f = 1;
33374a4d8c2SCharles.Forsyth 			if(debug['P'])
33474a4d8c2SCharles.Forsyth 				print("; merge; f=%d", f);
33574a4d8c2SCharles.Forsyth 		}
33674a4d8c2SCharles.Forsyth 		t = copyu(p, v2, A);
33774a4d8c2SCharles.Forsyth 		switch(t) {
33874a4d8c2SCharles.Forsyth 		case 2:	/* rar, cant split */
33974a4d8c2SCharles.Forsyth 			if(debug['P'])
34074a4d8c2SCharles.Forsyth 				print("; %Drar; return 0\n", v2);
34174a4d8c2SCharles.Forsyth 			return 0;
34274a4d8c2SCharles.Forsyth 
34374a4d8c2SCharles.Forsyth 		case 3:	/* set */
34474a4d8c2SCharles.Forsyth 			if(debug['P'])
34574a4d8c2SCharles.Forsyth 				print("; %Dset; return 1\n", v2);
34674a4d8c2SCharles.Forsyth 			return 1;
34774a4d8c2SCharles.Forsyth 
34874a4d8c2SCharles.Forsyth 		case 1:	/* used, substitute */
34974a4d8c2SCharles.Forsyth 		case 4:	/* use and set */
35074a4d8c2SCharles.Forsyth 			if(f) {
35174a4d8c2SCharles.Forsyth 				if(!debug['P'])
35274a4d8c2SCharles.Forsyth 					return 0;
35374a4d8c2SCharles.Forsyth 				if(t == 4)
35474a4d8c2SCharles.Forsyth 					print("; %Dused+set and f=%d; return 0\n", v2, f);
35574a4d8c2SCharles.Forsyth 				else
35674a4d8c2SCharles.Forsyth 					print("; %Dused and f=%d; return 0\n", v2, f);
35774a4d8c2SCharles.Forsyth 				return 0;
35874a4d8c2SCharles.Forsyth 			}
35974a4d8c2SCharles.Forsyth 			if(copyu(p, v2, v1)) {
36074a4d8c2SCharles.Forsyth 				if(debug['P'])
36174a4d8c2SCharles.Forsyth 					print("; sub fail; return 0\n");
36274a4d8c2SCharles.Forsyth 				return 0;
36374a4d8c2SCharles.Forsyth 			}
36474a4d8c2SCharles.Forsyth 			if(debug['P'])
36574a4d8c2SCharles.Forsyth 				print("; sub%D/%D", v2, v1);
36674a4d8c2SCharles.Forsyth 			if(t == 4) {
36774a4d8c2SCharles.Forsyth 				if(debug['P'])
36874a4d8c2SCharles.Forsyth 					print("; %Dused+set; return 1\n", v2);
36974a4d8c2SCharles.Forsyth 				return 1;
37074a4d8c2SCharles.Forsyth 			}
37174a4d8c2SCharles.Forsyth 			break;
37274a4d8c2SCharles.Forsyth 		}
37374a4d8c2SCharles.Forsyth 		if(!f) {
37474a4d8c2SCharles.Forsyth 			t = copyu(p, v1, A);
37574a4d8c2SCharles.Forsyth 			if(!f && (t == 2 || t == 3 || t == 4)) {
37674a4d8c2SCharles.Forsyth 				f = 1;
37774a4d8c2SCharles.Forsyth 				if(debug['P'])
37874a4d8c2SCharles.Forsyth 					print("; %Dset and !f; f=%d", v1, f);
37974a4d8c2SCharles.Forsyth 			}
38074a4d8c2SCharles.Forsyth 		}
38174a4d8c2SCharles.Forsyth 		if(debug['P'])
38274a4d8c2SCharles.Forsyth 			print("\n");
38374a4d8c2SCharles.Forsyth 		if(r->s2)
38474a4d8c2SCharles.Forsyth 			if(!copy1(v1, v2, r->s2, f))
38574a4d8c2SCharles.Forsyth 				return 0;
38674a4d8c2SCharles.Forsyth 	}
38774a4d8c2SCharles.Forsyth 	return 1;
38874a4d8c2SCharles.Forsyth }
38974a4d8c2SCharles.Forsyth 
39074a4d8c2SCharles.Forsyth /*
39174a4d8c2SCharles.Forsyth  * The idea is to remove redundant constants.
39274a4d8c2SCharles.Forsyth  *	$c1->v1
39374a4d8c2SCharles.Forsyth  *	($c1->v2 s/$c1/v1)*
39474a4d8c2SCharles.Forsyth  *	set v1  return
39574a4d8c2SCharles.Forsyth  * The v1->v2 should be eliminated by copy propagation.
39674a4d8c2SCharles.Forsyth  */
39774a4d8c2SCharles.Forsyth void
constprop(Adr * c1,Adr * v1,Reg * r)39874a4d8c2SCharles.Forsyth constprop(Adr *c1, Adr *v1, Reg *r)
39974a4d8c2SCharles.Forsyth {
40074a4d8c2SCharles.Forsyth 	Prog *p;
40174a4d8c2SCharles.Forsyth 
40274a4d8c2SCharles.Forsyth 	if(debug['C'])
40374a4d8c2SCharles.Forsyth 		print("constprop %D->%D\n", c1, v1);
40474a4d8c2SCharles.Forsyth 	for(; r != R; r = r->s1) {
40574a4d8c2SCharles.Forsyth 		p = r->prog;
40674a4d8c2SCharles.Forsyth 		if(debug['C'])
40774a4d8c2SCharles.Forsyth 			print("%P", p);
40874a4d8c2SCharles.Forsyth 		if(uniqp(r) == R) {
40974a4d8c2SCharles.Forsyth 			if(debug['C'])
41074a4d8c2SCharles.Forsyth 				print("; merge; return\n");
41174a4d8c2SCharles.Forsyth 			return;
41274a4d8c2SCharles.Forsyth 		}
41374a4d8c2SCharles.Forsyth 		if(p->as == AMOVW && copyas(&p->from, c1)) {
41474a4d8c2SCharles.Forsyth 				if(debug['C'])
41574a4d8c2SCharles.Forsyth 					print("; sub%D/%D", &p->from, v1);
41674a4d8c2SCharles.Forsyth 				p->from = *v1;
41774a4d8c2SCharles.Forsyth 		} else if(copyu(p, v1, A) > 1) {
41874a4d8c2SCharles.Forsyth 			if(debug['C'])
41974a4d8c2SCharles.Forsyth 				print("; %Dset; return\n", v1);
42074a4d8c2SCharles.Forsyth 			return;
42174a4d8c2SCharles.Forsyth 		}
42274a4d8c2SCharles.Forsyth 		if(debug['C'])
42374a4d8c2SCharles.Forsyth 			print("\n");
42474a4d8c2SCharles.Forsyth 		if(r->s2)
42574a4d8c2SCharles.Forsyth 			constprop(c1, v1, r->s2);
42674a4d8c2SCharles.Forsyth 	}
42774a4d8c2SCharles.Forsyth }
42874a4d8c2SCharles.Forsyth 
42974a4d8c2SCharles.Forsyth /*
43074a4d8c2SCharles.Forsyth  * return
43174a4d8c2SCharles.Forsyth  * 1 if v only used (and substitute),
43274a4d8c2SCharles.Forsyth  * 2 if read-alter-rewrite
43374a4d8c2SCharles.Forsyth  * 3 if set
43474a4d8c2SCharles.Forsyth  * 4 if set and used
43574a4d8c2SCharles.Forsyth  * 0 otherwise (not touched)
43674a4d8c2SCharles.Forsyth  */
43774a4d8c2SCharles.Forsyth int
copyu(Prog * p,Adr * v,Adr * s)43874a4d8c2SCharles.Forsyth copyu(Prog *p, Adr *v, Adr *s)
43974a4d8c2SCharles.Forsyth {
44074a4d8c2SCharles.Forsyth 
44174a4d8c2SCharles.Forsyth 	switch(p->as) {
44274a4d8c2SCharles.Forsyth 
44374a4d8c2SCharles.Forsyth 	default:
44474a4d8c2SCharles.Forsyth 		if(debug['P'])
4456e425a9dSCharles.Forsyth 			print(" (?)");
44674a4d8c2SCharles.Forsyth 		return 2;
44774a4d8c2SCharles.Forsyth 
44874a4d8c2SCharles.Forsyth 	case AMOVM:
44974a4d8c2SCharles.Forsyth 		if(v->type != D_REG)
45074a4d8c2SCharles.Forsyth 			return 0;
45174a4d8c2SCharles.Forsyth 		if(p->from.type == D_CONST) {	/* read reglist, read/rar */
45274a4d8c2SCharles.Forsyth 			if(s != A) {
45374a4d8c2SCharles.Forsyth 				if(p->from.offset&(1<<v->reg))
45474a4d8c2SCharles.Forsyth 					return 1;
45574a4d8c2SCharles.Forsyth 				if(copysub(&p->to, v, s, 1))
45674a4d8c2SCharles.Forsyth 					diag(Z, "movm dst being replaced");	// was return 1;
45774a4d8c2SCharles.Forsyth 				return 0;
45874a4d8c2SCharles.Forsyth 			}
45974a4d8c2SCharles.Forsyth 			if(copyau(&p->to, v))
46074a4d8c2SCharles.Forsyth 				return 2;		// register updated in thumb // was return 1;
46174a4d8c2SCharles.Forsyth 			if(p->from.offset&(1<<v->reg))
46274a4d8c2SCharles.Forsyth 				return 1;
46374a4d8c2SCharles.Forsyth 		} else {			/* read/rar, write reglist */
46474a4d8c2SCharles.Forsyth 			if(s != A) {
46574a4d8c2SCharles.Forsyth 				if(p->to.offset&(1<<v->reg))
46674a4d8c2SCharles.Forsyth 					return 1;
46774a4d8c2SCharles.Forsyth 				if(copysub(&p->from, v, s, 1))
46874a4d8c2SCharles.Forsyth 					diag(Z, "movm src being replaced");	// was return 1;
46974a4d8c2SCharles.Forsyth 				return 0;
47074a4d8c2SCharles.Forsyth 			}
47174a4d8c2SCharles.Forsyth 			if(copyau(&p->from, v)) {
47274a4d8c2SCharles.Forsyth 				// if(p->to.offset&(1<<v->reg))
47374a4d8c2SCharles.Forsyth 					// return 4;
47474a4d8c2SCharles.Forsyth 				return 2;		// register updated in thumb // was return 1;
47574a4d8c2SCharles.Forsyth 			}
47674a4d8c2SCharles.Forsyth 			if(p->to.offset&(1<<v->reg))
47774a4d8c2SCharles.Forsyth 				return 3;
47874a4d8c2SCharles.Forsyth 		}
47974a4d8c2SCharles.Forsyth 		return 0;
48074a4d8c2SCharles.Forsyth 
48174a4d8c2SCharles.Forsyth 	case ANOP:	/* read, write */
48274a4d8c2SCharles.Forsyth 	case AMOVW:
48374a4d8c2SCharles.Forsyth 	case AMOVF:
48474a4d8c2SCharles.Forsyth 	case AMOVD:
48574a4d8c2SCharles.Forsyth 	case AMOVH:
48674a4d8c2SCharles.Forsyth 	case AMOVHU:
48774a4d8c2SCharles.Forsyth 	case AMOVB:
48874a4d8c2SCharles.Forsyth 	case AMOVBU:
48974a4d8c2SCharles.Forsyth 	case AMOVDW:
49074a4d8c2SCharles.Forsyth 	case AMOVWD:
49174a4d8c2SCharles.Forsyth 	case AMOVFD:
49274a4d8c2SCharles.Forsyth 	case AMOVDF:
49374a4d8c2SCharles.Forsyth 		if(s != A) {
49474a4d8c2SCharles.Forsyth 			if(copysub(&p->from, v, s, 1))
49574a4d8c2SCharles.Forsyth 				return 1;
49674a4d8c2SCharles.Forsyth 			if(!copyas(&p->to, v))
49774a4d8c2SCharles.Forsyth 				if(copysub(&p->to, v, s, 1))
49874a4d8c2SCharles.Forsyth 					return 1;
49974a4d8c2SCharles.Forsyth 			return 0;
50074a4d8c2SCharles.Forsyth 		}
50174a4d8c2SCharles.Forsyth 		if(copyas(&p->to, v)) {
50274a4d8c2SCharles.Forsyth 			if(copyau(&p->from, v))
50374a4d8c2SCharles.Forsyth 				return 4;
50474a4d8c2SCharles.Forsyth 			return 3;
50574a4d8c2SCharles.Forsyth 		}
50674a4d8c2SCharles.Forsyth 		if(copyau(&p->from, v))
50774a4d8c2SCharles.Forsyth 			return 1;
50874a4d8c2SCharles.Forsyth 		if(copyau(&p->to, v))
50974a4d8c2SCharles.Forsyth 			return 1;
51074a4d8c2SCharles.Forsyth 		return 0;
51174a4d8c2SCharles.Forsyth 
51274a4d8c2SCharles.Forsyth 	case ASLL:
51374a4d8c2SCharles.Forsyth 	case ASRL:
51474a4d8c2SCharles.Forsyth 	case ASRA:
51574a4d8c2SCharles.Forsyth 	case AORR:
51674a4d8c2SCharles.Forsyth 	case AAND:
51774a4d8c2SCharles.Forsyth 	case AEOR:
51874a4d8c2SCharles.Forsyth 	case AMUL:
51974a4d8c2SCharles.Forsyth 	case ADIV:
52074a4d8c2SCharles.Forsyth 	case ADIVU:
52174a4d8c2SCharles.Forsyth 	case AADDF:
52274a4d8c2SCharles.Forsyth 	case AADDD:
52374a4d8c2SCharles.Forsyth 	case ASUBF:
52474a4d8c2SCharles.Forsyth 	case ASUBD:
52574a4d8c2SCharles.Forsyth 	case AMULF:
52674a4d8c2SCharles.Forsyth 	case AMULD:
52774a4d8c2SCharles.Forsyth 	case ADIVF:
52874a4d8c2SCharles.Forsyth 	case ADIVD:
52974a4d8c2SCharles.Forsyth 	case ACMPF:
53074a4d8c2SCharles.Forsyth 	case ACMPD:
53174a4d8c2SCharles.Forsyth 	case ACMP:
53274a4d8c2SCharles.Forsyth 	case ACMN:
53374a4d8c2SCharles.Forsyth 		if(copyas(&p->to, v))
53474a4d8c2SCharles.Forsyth 			return 2;
53574a4d8c2SCharles.Forsyth 		/*FALLTHROUGH*/
53674a4d8c2SCharles.Forsyth 
53774a4d8c2SCharles.Forsyth 	case AADD:	/* read, read, write */
53874a4d8c2SCharles.Forsyth 	case ASUB:
53974a4d8c2SCharles.Forsyth 		if(s != A) {
54074a4d8c2SCharles.Forsyth 			if(copysub(&p->from, v, s, 1))
54174a4d8c2SCharles.Forsyth 				return 1;
54274a4d8c2SCharles.Forsyth 			if(copysub1(p, v, s, 1))
54374a4d8c2SCharles.Forsyth 				return 1;
54474a4d8c2SCharles.Forsyth 			if(!copyas(&p->to, v))
54574a4d8c2SCharles.Forsyth 				if(copysub(&p->to, v, s, 1))
54674a4d8c2SCharles.Forsyth 					return 1;
54774a4d8c2SCharles.Forsyth 			return 0;
54874a4d8c2SCharles.Forsyth 		}
54974a4d8c2SCharles.Forsyth 		if(copyas(&p->to, v)) {
55074a4d8c2SCharles.Forsyth 			if(p->reg == NREG)
55174a4d8c2SCharles.Forsyth 				p->reg = p->to.reg;
55274a4d8c2SCharles.Forsyth 			if(copyau(&p->from, v))
55374a4d8c2SCharles.Forsyth 				return 4;
55474a4d8c2SCharles.Forsyth 			if(copyau1(p, v))
55574a4d8c2SCharles.Forsyth 				return 4;
55674a4d8c2SCharles.Forsyth 			return 3;
55774a4d8c2SCharles.Forsyth 		}
55874a4d8c2SCharles.Forsyth 		if(copyau(&p->from, v))
55974a4d8c2SCharles.Forsyth 			return 1;
56074a4d8c2SCharles.Forsyth 		if(copyau1(p, v))
56174a4d8c2SCharles.Forsyth 			return 1;
56274a4d8c2SCharles.Forsyth 		if(copyau(&p->to, v))
56374a4d8c2SCharles.Forsyth 			return 1;
56474a4d8c2SCharles.Forsyth 		return 0;
56574a4d8c2SCharles.Forsyth 
56674a4d8c2SCharles.Forsyth 	case ABEQ:	/* read, read */
56774a4d8c2SCharles.Forsyth 	case ABNE:
56874a4d8c2SCharles.Forsyth 	case ABCS:
56974a4d8c2SCharles.Forsyth 	case ABHS:
57074a4d8c2SCharles.Forsyth 	case ABCC:
57174a4d8c2SCharles.Forsyth 	case ABLO:
57274a4d8c2SCharles.Forsyth 	case ABMI:
57374a4d8c2SCharles.Forsyth 	case ABPL:
57474a4d8c2SCharles.Forsyth 	case ABVS:
57574a4d8c2SCharles.Forsyth 	case ABVC:
57674a4d8c2SCharles.Forsyth 	case ABHI:
57774a4d8c2SCharles.Forsyth 	case ABLS:
57874a4d8c2SCharles.Forsyth 	case ABGE:
57974a4d8c2SCharles.Forsyth 	case ABLT:
58074a4d8c2SCharles.Forsyth 	case ABGT:
58174a4d8c2SCharles.Forsyth 	case ABLE:
58274a4d8c2SCharles.Forsyth 		if(s != A) {
58374a4d8c2SCharles.Forsyth 			if(copysub(&p->from, v, s, 1))
58474a4d8c2SCharles.Forsyth 				return 1;
58574a4d8c2SCharles.Forsyth 			return copysub1(p, v, s, 1);
58674a4d8c2SCharles.Forsyth 		}
58774a4d8c2SCharles.Forsyth 		if(copyau(&p->from, v))
58874a4d8c2SCharles.Forsyth 			return 1;
58974a4d8c2SCharles.Forsyth 		if(copyau1(p, v))
59074a4d8c2SCharles.Forsyth 			return 1;
59174a4d8c2SCharles.Forsyth 		return 0;
59274a4d8c2SCharles.Forsyth 
59374a4d8c2SCharles.Forsyth 	case AB:	/* funny */
59474a4d8c2SCharles.Forsyth 		if(s != A) {
59574a4d8c2SCharles.Forsyth 			if(copysub(&p->to, v, s, 1))
59674a4d8c2SCharles.Forsyth 				return 1;
59774a4d8c2SCharles.Forsyth 			return 0;
59874a4d8c2SCharles.Forsyth 		}
59974a4d8c2SCharles.Forsyth 		if(copyau(&p->to, v))
60074a4d8c2SCharles.Forsyth 			return 1;
60174a4d8c2SCharles.Forsyth 		return 0;
60274a4d8c2SCharles.Forsyth 
60374a4d8c2SCharles.Forsyth 	case ARET:	/* funny */
60474a4d8c2SCharles.Forsyth 		if(v->type == D_REG)
60574a4d8c2SCharles.Forsyth 		if(v->reg == REGRET)
60674a4d8c2SCharles.Forsyth 			return 2;
60774a4d8c2SCharles.Forsyth 		if(v->type == D_FREG)
60874a4d8c2SCharles.Forsyth 		if(v->reg == FREGRET)
60974a4d8c2SCharles.Forsyth 			return 2;
61074a4d8c2SCharles.Forsyth 
61174a4d8c2SCharles.Forsyth 	case ABL:	/* funny */
61274a4d8c2SCharles.Forsyth 	case ABX:
61374a4d8c2SCharles.Forsyth 		if(v->type == D_REG) {
61474a4d8c2SCharles.Forsyth 			if(v->reg <= REGEXT && v->reg > exregoffset)
61574a4d8c2SCharles.Forsyth 				return 2;
61674a4d8c2SCharles.Forsyth 			if(v->reg == REGARG)
61774a4d8c2SCharles.Forsyth 				return 2;
61874a4d8c2SCharles.Forsyth 		}
61974a4d8c2SCharles.Forsyth 		if(v->type == D_FREG)
62074a4d8c2SCharles.Forsyth 			if(v->reg <= FREGEXT && v->reg > exfregoffset)
62174a4d8c2SCharles.Forsyth 				return 2;
62274a4d8c2SCharles.Forsyth 
62374a4d8c2SCharles.Forsyth 		if(s != A) {
62474a4d8c2SCharles.Forsyth 			if(copysub(&p->to, v, s, 1))
62574a4d8c2SCharles.Forsyth 				return 1;
62674a4d8c2SCharles.Forsyth 			return 0;
62774a4d8c2SCharles.Forsyth 		}
62874a4d8c2SCharles.Forsyth 		if(copyau(&p->to, v))
62974a4d8c2SCharles.Forsyth 			return 4;
63074a4d8c2SCharles.Forsyth 		return 3;
63174a4d8c2SCharles.Forsyth 
63274a4d8c2SCharles.Forsyth 	case ATEXT:	/* funny */
63374a4d8c2SCharles.Forsyth 		if(v->type == D_REG)
63474a4d8c2SCharles.Forsyth 			if(v->reg == REGARG)
63574a4d8c2SCharles.Forsyth 				return 3;
63674a4d8c2SCharles.Forsyth 		return 0;
63774a4d8c2SCharles.Forsyth 	}
638*d67b7dadSforsyth 	/* not reached */
63974a4d8c2SCharles.Forsyth }
64074a4d8c2SCharles.Forsyth 
64174a4d8c2SCharles.Forsyth int
a2type(Prog * p)64274a4d8c2SCharles.Forsyth a2type(Prog *p)
64374a4d8c2SCharles.Forsyth {
64474a4d8c2SCharles.Forsyth 
64574a4d8c2SCharles.Forsyth 	switch(p->as) {
64674a4d8c2SCharles.Forsyth 
64774a4d8c2SCharles.Forsyth 	case ACMP:
64874a4d8c2SCharles.Forsyth 	case ACMN:
64974a4d8c2SCharles.Forsyth 
65074a4d8c2SCharles.Forsyth 	case AADD:
65174a4d8c2SCharles.Forsyth 	case ASUB:
65274a4d8c2SCharles.Forsyth 	case ASLL:
65374a4d8c2SCharles.Forsyth 	case ASRL:
65474a4d8c2SCharles.Forsyth 	case ASRA:
65574a4d8c2SCharles.Forsyth 	case AORR:
65674a4d8c2SCharles.Forsyth 	case AAND:
65774a4d8c2SCharles.Forsyth 	case AEOR:
65874a4d8c2SCharles.Forsyth 	case AMUL:
65974a4d8c2SCharles.Forsyth 	case ADIV:
66074a4d8c2SCharles.Forsyth 	case ADIVU:
66174a4d8c2SCharles.Forsyth 		return D_REG;
66274a4d8c2SCharles.Forsyth 
66374a4d8c2SCharles.Forsyth 	case ACMPF:
66474a4d8c2SCharles.Forsyth 	case ACMPD:
66574a4d8c2SCharles.Forsyth 
66674a4d8c2SCharles.Forsyth 	case AADDF:
66774a4d8c2SCharles.Forsyth 	case AADDD:
66874a4d8c2SCharles.Forsyth 	case ASUBF:
66974a4d8c2SCharles.Forsyth 	case ASUBD:
67074a4d8c2SCharles.Forsyth 	case AMULF:
67174a4d8c2SCharles.Forsyth 	case AMULD:
67274a4d8c2SCharles.Forsyth 	case ADIVF:
67374a4d8c2SCharles.Forsyth 	case ADIVD:
67474a4d8c2SCharles.Forsyth 		return D_FREG;
67574a4d8c2SCharles.Forsyth 	}
67674a4d8c2SCharles.Forsyth 	return D_NONE;
67774a4d8c2SCharles.Forsyth }
67874a4d8c2SCharles.Forsyth 
67974a4d8c2SCharles.Forsyth /*
68074a4d8c2SCharles.Forsyth  * direct reference,
68174a4d8c2SCharles.Forsyth  * could be set/use depending on
68274a4d8c2SCharles.Forsyth  * semantics
68374a4d8c2SCharles.Forsyth  */
68474a4d8c2SCharles.Forsyth int
copyas(Adr * a,Adr * v)68574a4d8c2SCharles.Forsyth copyas(Adr *a, Adr *v)
68674a4d8c2SCharles.Forsyth {
68774a4d8c2SCharles.Forsyth 
68874a4d8c2SCharles.Forsyth 	if(regtyp(v)) {
68974a4d8c2SCharles.Forsyth 		if(a->type == v->type)
69074a4d8c2SCharles.Forsyth 		if(a->reg == v->reg)
69174a4d8c2SCharles.Forsyth 			return 1;
69274a4d8c2SCharles.Forsyth 	} else if(v->type == D_CONST) {		/* for constprop */
69374a4d8c2SCharles.Forsyth 		if(a->type == v->type)
69474a4d8c2SCharles.Forsyth 		if(a->name == v->name)
69574a4d8c2SCharles.Forsyth 		if(a->sym == v->sym)
69674a4d8c2SCharles.Forsyth 		if(a->reg == v->reg)
69774a4d8c2SCharles.Forsyth 		if(a->offset == v->offset)
69874a4d8c2SCharles.Forsyth 			return 1;
69974a4d8c2SCharles.Forsyth 	}
70074a4d8c2SCharles.Forsyth 	return 0;
70174a4d8c2SCharles.Forsyth }
70274a4d8c2SCharles.Forsyth 
70374a4d8c2SCharles.Forsyth /*
70474a4d8c2SCharles.Forsyth  * either direct or indirect
70574a4d8c2SCharles.Forsyth  */
70674a4d8c2SCharles.Forsyth int
copyau(Adr * a,Adr * v)70774a4d8c2SCharles.Forsyth copyau(Adr *a, Adr *v)
70874a4d8c2SCharles.Forsyth {
70974a4d8c2SCharles.Forsyth 
71074a4d8c2SCharles.Forsyth 	if(copyas(a, v))
71174a4d8c2SCharles.Forsyth 		return 1;
71274a4d8c2SCharles.Forsyth 	if(v->type == D_REG) {
71374a4d8c2SCharles.Forsyth 		if(a->type == D_OREG) {
71474a4d8c2SCharles.Forsyth 			if(v->reg == a->reg)
71574a4d8c2SCharles.Forsyth 				return 1;
71674a4d8c2SCharles.Forsyth 		}
71774a4d8c2SCharles.Forsyth 	}
71874a4d8c2SCharles.Forsyth 	return 0;
71974a4d8c2SCharles.Forsyth }
72074a4d8c2SCharles.Forsyth 
72174a4d8c2SCharles.Forsyth int
copyau1(Prog * p,Adr * v)72274a4d8c2SCharles.Forsyth copyau1(Prog *p, Adr *v)
72374a4d8c2SCharles.Forsyth {
72474a4d8c2SCharles.Forsyth 
72574a4d8c2SCharles.Forsyth 	if(regtyp(v)) {
72674a4d8c2SCharles.Forsyth 		if(a2type(p) == v->type)
72774a4d8c2SCharles.Forsyth 		if(p->reg == v->reg) {
72874a4d8c2SCharles.Forsyth 			if(a2type(p) != v->type)
72974a4d8c2SCharles.Forsyth 				print("botch a2type %P\n", p);
73074a4d8c2SCharles.Forsyth 			return 1;
73174a4d8c2SCharles.Forsyth 		}
73274a4d8c2SCharles.Forsyth 	}
73374a4d8c2SCharles.Forsyth 	return 0;
73474a4d8c2SCharles.Forsyth }
73574a4d8c2SCharles.Forsyth 
73674a4d8c2SCharles.Forsyth /*
73774a4d8c2SCharles.Forsyth  * substitute s for v in a
73874a4d8c2SCharles.Forsyth  * return failure to substitute
73974a4d8c2SCharles.Forsyth  */
74074a4d8c2SCharles.Forsyth int
copysub(Adr * a,Adr * v,Adr * s,int f)74174a4d8c2SCharles.Forsyth copysub(Adr *a, Adr *v, Adr *s, int f)
74274a4d8c2SCharles.Forsyth {
74374a4d8c2SCharles.Forsyth 
74474a4d8c2SCharles.Forsyth 	if(f)
74574a4d8c2SCharles.Forsyth 	if(copyau(a, v)) {
74674a4d8c2SCharles.Forsyth 		a->reg = s->reg;
74774a4d8c2SCharles.Forsyth 	}
74874a4d8c2SCharles.Forsyth 	return 0;
74974a4d8c2SCharles.Forsyth }
75074a4d8c2SCharles.Forsyth 
75174a4d8c2SCharles.Forsyth int
copysub1(Prog * p1,Adr * v,Adr * s,int f)75274a4d8c2SCharles.Forsyth copysub1(Prog *p1, Adr *v, Adr *s, int f)
75374a4d8c2SCharles.Forsyth {
75474a4d8c2SCharles.Forsyth 
75574a4d8c2SCharles.Forsyth 	if(f)
75674a4d8c2SCharles.Forsyth 	if(copyau1(p1, v))
75774a4d8c2SCharles.Forsyth 		p1->reg = s->reg;
75874a4d8c2SCharles.Forsyth 	return 0;
75974a4d8c2SCharles.Forsyth }
760