xref: /inferno-os/utils/ic/peep.c (revision a93f6c888f6d530420fbb54e2f7fa4572cdc5208)
1*6e84dc96SRichard Miller #include "gc.h"
2*6e84dc96SRichard Miller 
3*6e84dc96SRichard Miller void
peep(void)4*6e84dc96SRichard Miller peep(void)
5*6e84dc96SRichard Miller {
6*6e84dc96SRichard Miller 	Reg *r, *r1, *r2;
7*6e84dc96SRichard Miller 	Prog *p, *p1;
8*6e84dc96SRichard Miller 	int t;
9*6e84dc96SRichard Miller /*
10*6e84dc96SRichard Miller  * complete R structure
11*6e84dc96SRichard Miller  */
12*6e84dc96SRichard Miller 	t = 0;
13*6e84dc96SRichard Miller 	for(r=firstr; r!=R; r=r1) {
14*6e84dc96SRichard Miller 		r1 = r->link;
15*6e84dc96SRichard Miller 		if(r1 == R)
16*6e84dc96SRichard Miller 			break;
17*6e84dc96SRichard Miller 		p = r->prog->link;
18*6e84dc96SRichard Miller 		while(p != r1->prog)
19*6e84dc96SRichard Miller 		switch(p->as) {
20*6e84dc96SRichard Miller 		default:
21*6e84dc96SRichard Miller 			r2 = rega();
22*6e84dc96SRichard Miller 			r->link = r2;
23*6e84dc96SRichard Miller 			r2->link = r1;
24*6e84dc96SRichard Miller 
25*6e84dc96SRichard Miller 			r2->prog = p;
26*6e84dc96SRichard Miller 			r2->p1 = r;
27*6e84dc96SRichard Miller 			r->s1 = r2;
28*6e84dc96SRichard Miller 			r2->s1 = r1;
29*6e84dc96SRichard Miller 			r1->p1 = r2;
30*6e84dc96SRichard Miller 
31*6e84dc96SRichard Miller 			r = r2;
32*6e84dc96SRichard Miller 			t++;
33*6e84dc96SRichard Miller 
34*6e84dc96SRichard Miller 		case ADATA:
35*6e84dc96SRichard Miller 		case AGLOBL:
36*6e84dc96SRichard Miller 		case ANAME:
37*6e84dc96SRichard Miller 		case ASIGNAME:
38*6e84dc96SRichard Miller 			p = p->link;
39*6e84dc96SRichard Miller 		}
40*6e84dc96SRichard Miller 	}
41*6e84dc96SRichard Miller 
42*6e84dc96SRichard Miller 	/*
43*6e84dc96SRichard Miller 	 * look for MOVB x,R; MOVB R,R	=> MOVB x,R
44*6e84dc96SRichard Miller 	 * look for MOVB x,R; MOVB R,S	=> MOVB x,R; MOVW R,S
45*6e84dc96SRichard Miller 	 */
46*6e84dc96SRichard Miller 	for(r=firstr; r!=R; r=r->link) {
47*6e84dc96SRichard Miller 		p = r->prog;
48*6e84dc96SRichard Miller 		switch(p->as) {
49*6e84dc96SRichard Miller 		default:
50*6e84dc96SRichard Miller 			continue;
51*6e84dc96SRichard Miller 		case AMOVH:
52*6e84dc96SRichard Miller 		case AMOVHU:
53*6e84dc96SRichard Miller 		case AMOVB:
54*6e84dc96SRichard Miller 		case AMOVBU:
55*6e84dc96SRichard Miller 			if(p->to.type != D_REG)
56*6e84dc96SRichard Miller 				continue;
57*6e84dc96SRichard Miller 			break;
58*6e84dc96SRichard Miller 		}
59*6e84dc96SRichard Miller 		r1 = r->link;
60*6e84dc96SRichard Miller 		if(r1 == R)
61*6e84dc96SRichard Miller 			continue;
62*6e84dc96SRichard Miller 		p1 = r1->prog;
63*6e84dc96SRichard Miller 		if(p1->as != p->as)
64*6e84dc96SRichard Miller 			continue;
65*6e84dc96SRichard Miller 		if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
66*6e84dc96SRichard Miller 			continue;
67*6e84dc96SRichard Miller 		if(p1->to.type != D_REG)
68*6e84dc96SRichard Miller 			continue;
69*6e84dc96SRichard Miller 		if(p1->to.reg == p->to.reg)
70*6e84dc96SRichard Miller 			excise(r1);
71*6e84dc96SRichard Miller 		else
72*6e84dc96SRichard Miller 			p1->as = AMOVW;
73*6e84dc96SRichard Miller 	}
74*6e84dc96SRichard Miller 
75*6e84dc96SRichard Miller loop1:
76*6e84dc96SRichard Miller 	t = 0;
77*6e84dc96SRichard Miller 	for(r=firstr; r!=R; r=r->link) {
78*6e84dc96SRichard Miller 		p = r->prog;
79*6e84dc96SRichard Miller 		if(p->as == AMOVW || p->as == AMOVWU || p->as == AMOV || p->as == AMOVF || p->as == AMOVD)
80*6e84dc96SRichard Miller 		if(regtyp(&p->to)) {
81*6e84dc96SRichard Miller 			if(regtyp(&p->from))
82*6e84dc96SRichard Miller 			if(p->from.type == p->to.type) {
83*6e84dc96SRichard Miller 				if(copyprop(r)) {
84*6e84dc96SRichard Miller 					excise(r);
85*6e84dc96SRichard Miller 					t++;
86*6e84dc96SRichard Miller 				} else
87*6e84dc96SRichard Miller 				if(subprop(r) && copyprop(r)) {
88*6e84dc96SRichard Miller 					excise(r);
89*6e84dc96SRichard Miller 					t++;
90*6e84dc96SRichard Miller 				}
91*6e84dc96SRichard Miller 			}
92*6e84dc96SRichard Miller 			if(regzer(&p->from))
93*6e84dc96SRichard Miller 			if(p->to.type == D_REG) {
94*6e84dc96SRichard Miller 				p->from.type = D_REG;
95*6e84dc96SRichard Miller 				p->from.reg = 0;
96*6e84dc96SRichard Miller 				if(copyprop(r)) {
97*6e84dc96SRichard Miller 					excise(r);
98*6e84dc96SRichard Miller 					t++;
99*6e84dc96SRichard Miller 				} else
100*6e84dc96SRichard Miller 				if(subprop(r) && copyprop(r)) {
101*6e84dc96SRichard Miller 					excise(r);
102*6e84dc96SRichard Miller 					t++;
103*6e84dc96SRichard Miller 				}
104*6e84dc96SRichard Miller 			}
105*6e84dc96SRichard Miller 		}
106*6e84dc96SRichard Miller 	}
107*6e84dc96SRichard Miller 	if(t)
108*6e84dc96SRichard Miller 		goto loop1;
109*6e84dc96SRichard Miller }
110*6e84dc96SRichard Miller 
111*6e84dc96SRichard Miller void
excise(Reg * r)112*6e84dc96SRichard Miller excise(Reg *r)
113*6e84dc96SRichard Miller {
114*6e84dc96SRichard Miller 	Prog *p;
115*6e84dc96SRichard Miller 
116*6e84dc96SRichard Miller 	p = r->prog;
117*6e84dc96SRichard Miller 	p->as = ANOP;
118*6e84dc96SRichard Miller 	p->from = zprog.from;
119*6e84dc96SRichard Miller 	p->to = zprog.to;
120*6e84dc96SRichard Miller 	p->reg = zprog.reg; /**/
121*6e84dc96SRichard Miller }
122*6e84dc96SRichard Miller 
123*6e84dc96SRichard Miller Reg*
uniqp(Reg * r)124*6e84dc96SRichard Miller uniqp(Reg *r)
125*6e84dc96SRichard Miller {
126*6e84dc96SRichard Miller 	Reg *r1;
127*6e84dc96SRichard Miller 
128*6e84dc96SRichard Miller 	r1 = r->p1;
129*6e84dc96SRichard Miller 	if(r1 == R) {
130*6e84dc96SRichard Miller 		r1 = r->p2;
131*6e84dc96SRichard Miller 		if(r1 == R || r1->p2link != R)
132*6e84dc96SRichard Miller 			return R;
133*6e84dc96SRichard Miller 	} else
134*6e84dc96SRichard Miller 		if(r->p2 != R)
135*6e84dc96SRichard Miller 			return R;
136*6e84dc96SRichard Miller 	return r1;
137*6e84dc96SRichard Miller }
138*6e84dc96SRichard Miller 
139*6e84dc96SRichard Miller Reg*
uniqs(Reg * r)140*6e84dc96SRichard Miller uniqs(Reg *r)
141*6e84dc96SRichard Miller {
142*6e84dc96SRichard Miller 	Reg *r1;
143*6e84dc96SRichard Miller 
144*6e84dc96SRichard Miller 	r1 = r->s1;
145*6e84dc96SRichard Miller 	if(r1 == R) {
146*6e84dc96SRichard Miller 		r1 = r->s2;
147*6e84dc96SRichard Miller 		if(r1 == R)
148*6e84dc96SRichard Miller 			return R;
149*6e84dc96SRichard Miller 	} else
150*6e84dc96SRichard Miller 		if(r->s2 != R)
151*6e84dc96SRichard Miller 			return R;
152*6e84dc96SRichard Miller 	return r1;
153*6e84dc96SRichard Miller }
154*6e84dc96SRichard Miller 
155*6e84dc96SRichard Miller int
regzer(Adr * a)156*6e84dc96SRichard Miller regzer(Adr *a)
157*6e84dc96SRichard Miller {
158*6e84dc96SRichard Miller 
159*6e84dc96SRichard Miller 	if(a->type == D_CONST)
160*6e84dc96SRichard Miller 		if(a->sym == S)
161*6e84dc96SRichard Miller 			if(a->offset == 0)
162*6e84dc96SRichard Miller 				return 1;
163*6e84dc96SRichard Miller 	if(a->type == D_REG)
164*6e84dc96SRichard Miller 		if(a->reg == 0)
165*6e84dc96SRichard Miller 			return 1;
166*6e84dc96SRichard Miller 	return 0;
167*6e84dc96SRichard Miller }
168*6e84dc96SRichard Miller 
169*6e84dc96SRichard Miller int
regtyp(Adr * a)170*6e84dc96SRichard Miller regtyp(Adr *a)
171*6e84dc96SRichard Miller {
172*6e84dc96SRichard Miller 
173*6e84dc96SRichard Miller 	if(a->type == D_REG) {
174*6e84dc96SRichard Miller 		if(a->reg != 0)
175*6e84dc96SRichard Miller 			return 1;
176*6e84dc96SRichard Miller 		return 0;
177*6e84dc96SRichard Miller 	}
178*6e84dc96SRichard Miller 	if(a->type == D_FREG)
179*6e84dc96SRichard Miller 		return 1;
180*6e84dc96SRichard Miller 	return 0;
181*6e84dc96SRichard Miller }
182*6e84dc96SRichard Miller 
183*6e84dc96SRichard Miller /*
184*6e84dc96SRichard Miller  * the idea is to substitute
185*6e84dc96SRichard Miller  * one register for another
186*6e84dc96SRichard Miller  * from one MOV to another
187*6e84dc96SRichard Miller  *	MOV	a, R0
188*6e84dc96SRichard Miller  *	ADD	b, R0	/ no use of R1
189*6e84dc96SRichard Miller  *	MOV	R0, R1
190*6e84dc96SRichard Miller  * would be converted to
191*6e84dc96SRichard Miller  *	MOV	a, R1
192*6e84dc96SRichard Miller  *	ADD	b, R1
193*6e84dc96SRichard Miller  *	MOV	R1, R0
194*6e84dc96SRichard Miller  * hopefully, then the former or latter MOV
195*6e84dc96SRichard Miller  * will be eliminated by copy propagation.
196*6e84dc96SRichard Miller  */
197*6e84dc96SRichard Miller int
subprop(Reg * r0)198*6e84dc96SRichard Miller subprop(Reg *r0)
199*6e84dc96SRichard Miller {
200*6e84dc96SRichard Miller 	Prog *p;
201*6e84dc96SRichard Miller 	Adr *v1, *v2;
202*6e84dc96SRichard Miller 	Reg *r;
203*6e84dc96SRichard Miller 	int t;
204*6e84dc96SRichard Miller 
205*6e84dc96SRichard Miller 	p = r0->prog;
206*6e84dc96SRichard Miller 	v1 = &p->from;
207*6e84dc96SRichard Miller 	if(!regtyp(v1))
208*6e84dc96SRichard Miller 		return 0;
209*6e84dc96SRichard Miller 	v2 = &p->to;
210*6e84dc96SRichard Miller 	if(!regtyp(v2))
211*6e84dc96SRichard Miller 		return 0;
212*6e84dc96SRichard Miller 	for(r=uniqp(r0); r!=R; r=uniqp(r)) {
213*6e84dc96SRichard Miller 		if(uniqs(r) == R)
214*6e84dc96SRichard Miller 			break;
215*6e84dc96SRichard Miller 		p = r->prog;
216*6e84dc96SRichard Miller 		switch(p->as) {
217*6e84dc96SRichard Miller 		case AJAL:
218*6e84dc96SRichard Miller 			return 0;
219*6e84dc96SRichard Miller 
220*6e84dc96SRichard Miller 		case ASLT:
221*6e84dc96SRichard Miller 		case ASLTU:
222*6e84dc96SRichard Miller 		case ASGT:
223*6e84dc96SRichard Miller 		case ASGTU:
224*6e84dc96SRichard Miller 
225*6e84dc96SRichard Miller 		case AADD:  case AADDW:
226*6e84dc96SRichard Miller 		case ASUB:  case ASUBW:
227*6e84dc96SRichard Miller 		case ASLL:  case ASLLW:
228*6e84dc96SRichard Miller 		case ASRL:  case ASRLW:
229*6e84dc96SRichard Miller 		case ASRA:  case ASRAW:
230*6e84dc96SRichard Miller 		case AOR:
231*6e84dc96SRichard Miller 		case AAND:
232*6e84dc96SRichard Miller 		case AXOR:
233*6e84dc96SRichard Miller 		case AMUL:  case AMULW:
234*6e84dc96SRichard Miller 		case ADIV:  case ADIVW:
235*6e84dc96SRichard Miller 		case ADIVU: case ADIVUW:
236*6e84dc96SRichard Miller 
237*6e84dc96SRichard Miller 		case AADDD:
238*6e84dc96SRichard Miller 		case AADDF:
239*6e84dc96SRichard Miller 		case ASUBD:
240*6e84dc96SRichard Miller 		case ASUBF:
241*6e84dc96SRichard Miller 		case AMULD:
242*6e84dc96SRichard Miller 		case AMULF:
243*6e84dc96SRichard Miller 		case ADIVD:
244*6e84dc96SRichard Miller 		case ADIVF:
245*6e84dc96SRichard Miller 			if(p->to.type == v1->type)
246*6e84dc96SRichard Miller 			if(p->to.reg == v1->reg) {
247*6e84dc96SRichard Miller 				if(p->reg == NREG)
248*6e84dc96SRichard Miller 					p->reg = p->to.reg;
249*6e84dc96SRichard Miller 				goto gotit;
250*6e84dc96SRichard Miller 			}
251*6e84dc96SRichard Miller 			break;
252*6e84dc96SRichard Miller 
253*6e84dc96SRichard Miller 		case AMOVF:
254*6e84dc96SRichard Miller 		case AMOVD:
255*6e84dc96SRichard Miller 		case AMOVW: case AMOVWU: case AMOV:
256*6e84dc96SRichard Miller 			if(p->to.type == v1->type)
257*6e84dc96SRichard Miller 			if(p->to.reg == v1->reg)
258*6e84dc96SRichard Miller 				goto gotit;
259*6e84dc96SRichard Miller 			break;
260*6e84dc96SRichard Miller 		}
261*6e84dc96SRichard Miller 		if(copyau(&p->from, v2) ||
262*6e84dc96SRichard Miller 		   copyau1(p, v2) ||
263*6e84dc96SRichard Miller 		   copyau(&p->to, v2))
264*6e84dc96SRichard Miller 			break;
265*6e84dc96SRichard Miller 		if(copysub(&p->from, v1, v2, 0) ||
266*6e84dc96SRichard Miller 		   copysub1(p, v1, v2, 0) ||
267*6e84dc96SRichard Miller 		   copysub(&p->to, v1, v2, 0))
268*6e84dc96SRichard Miller 			break;
269*6e84dc96SRichard Miller 	}
270*6e84dc96SRichard Miller 	return 0;
271*6e84dc96SRichard Miller 
272*6e84dc96SRichard Miller gotit:
273*6e84dc96SRichard Miller 	copysub(&p->to, v1, v2, 1);
274*6e84dc96SRichard Miller 	if(debug['P']) {
275*6e84dc96SRichard Miller 		print("gotit: %D->%D\n%P", v1, v2, r->prog);
276*6e84dc96SRichard Miller 		if(p->from.type == v2->type)
277*6e84dc96SRichard Miller 			print(" excise");
278*6e84dc96SRichard Miller 		print("\n");
279*6e84dc96SRichard Miller 	}
280*6e84dc96SRichard Miller 	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
281*6e84dc96SRichard Miller 		p = r->prog;
282*6e84dc96SRichard Miller 		copysub(&p->from, v1, v2, 1);
283*6e84dc96SRichard Miller 		copysub1(p, v1, v2, 1);
284*6e84dc96SRichard Miller 		copysub(&p->to, v1, v2, 1);
285*6e84dc96SRichard Miller 		if(debug['P'])
286*6e84dc96SRichard Miller 			print("%P\n", r->prog);
287*6e84dc96SRichard Miller 	}
288*6e84dc96SRichard Miller 	t = v1->reg;
289*6e84dc96SRichard Miller 	v1->reg = v2->reg;
290*6e84dc96SRichard Miller 	v2->reg = t;
291*6e84dc96SRichard Miller 	if(debug['P'])
292*6e84dc96SRichard Miller 		print("%P last\n", r->prog);
293*6e84dc96SRichard Miller 	return 1;
294*6e84dc96SRichard Miller }
295*6e84dc96SRichard Miller 
296*6e84dc96SRichard Miller /*
297*6e84dc96SRichard Miller  * The idea is to remove redundant copies.
298*6e84dc96SRichard Miller  *	v1->v2	F=0
299*6e84dc96SRichard Miller  *	(use v2	s/v2/v1/)*
300*6e84dc96SRichard Miller  *	set v1	F=1
301*6e84dc96SRichard Miller  *	use v2	return fail
302*6e84dc96SRichard Miller  *	-----------------
303*6e84dc96SRichard Miller  *	v1->v2	F=0
304*6e84dc96SRichard Miller  *	(use v2	s/v2/v1/)*
305*6e84dc96SRichard Miller  *	set v1	F=1
306*6e84dc96SRichard Miller  *	set v2	return success
307*6e84dc96SRichard Miller  */
308*6e84dc96SRichard Miller int
copyprop(Reg * r0)309*6e84dc96SRichard Miller copyprop(Reg *r0)
310*6e84dc96SRichard Miller {
311*6e84dc96SRichard Miller 	Prog *p;
312*6e84dc96SRichard Miller 	Adr *v1, *v2;
313*6e84dc96SRichard Miller 	Reg *r;
314*6e84dc96SRichard Miller 
315*6e84dc96SRichard Miller 	p = r0->prog;
316*6e84dc96SRichard Miller 	v1 = &p->from;
317*6e84dc96SRichard Miller 	v2 = &p->to;
318*6e84dc96SRichard Miller 	if(copyas(v1, v2))
319*6e84dc96SRichard Miller 		return 1;
320*6e84dc96SRichard Miller 	for(r=firstr; r!=R; r=r->link)
321*6e84dc96SRichard Miller 		r->active = 0;
322*6e84dc96SRichard Miller 	return copy1(v1, v2, r0->s1, 0);
323*6e84dc96SRichard Miller }
324*6e84dc96SRichard Miller 
325*6e84dc96SRichard Miller int
copy1(Adr * v1,Adr * v2,Reg * r,int f)326*6e84dc96SRichard Miller copy1(Adr *v1, Adr *v2, Reg *r, int f)
327*6e84dc96SRichard Miller {
328*6e84dc96SRichard Miller 	int t;
329*6e84dc96SRichard Miller 	Prog *p;
330*6e84dc96SRichard Miller 
331*6e84dc96SRichard Miller 	if(r->active) {
332*6e84dc96SRichard Miller 		if(debug['P'])
333*6e84dc96SRichard Miller 			print("act set; return 1\n");
334*6e84dc96SRichard Miller 		return 1;
335*6e84dc96SRichard Miller 	}
336*6e84dc96SRichard Miller 	r->active = 1;
337*6e84dc96SRichard Miller 	if(debug['P'])
338*6e84dc96SRichard Miller 		print("copy %D->%D f=%d\n", v1, v2, f);
339*6e84dc96SRichard Miller 	for(; r != R; r = r->s1) {
340*6e84dc96SRichard Miller 		p = r->prog;
341*6e84dc96SRichard Miller 		if(debug['P'])
342*6e84dc96SRichard Miller 			print("%P", p);
343*6e84dc96SRichard Miller 		if(!f && uniqp(r) == R) {
344*6e84dc96SRichard Miller 			f = 1;
345*6e84dc96SRichard Miller 			if(debug['P'])
346*6e84dc96SRichard Miller 				print("; merge; f=%d", f);
347*6e84dc96SRichard Miller 		}
348*6e84dc96SRichard Miller 		t = copyu(p, v2, A);
349*6e84dc96SRichard Miller 		switch(t) {
350*6e84dc96SRichard Miller 		case 2:	/* rar, cant split */
351*6e84dc96SRichard Miller 			if(debug['P'])
352*6e84dc96SRichard Miller 				print("; %Drar; return 0\n", v2);
353*6e84dc96SRichard Miller 			return 0;
354*6e84dc96SRichard Miller 
355*6e84dc96SRichard Miller 		case 3:	/* set */
356*6e84dc96SRichard Miller 			if(debug['P'])
357*6e84dc96SRichard Miller 				print("; %Dset; return 1\n", v2);
358*6e84dc96SRichard Miller 			return 1;
359*6e84dc96SRichard Miller 
360*6e84dc96SRichard Miller 		case 1:	/* used, substitute */
361*6e84dc96SRichard Miller 		case 4:	/* use and set */
362*6e84dc96SRichard Miller 			if(f) {
363*6e84dc96SRichard Miller 				if(!debug['P'])
364*6e84dc96SRichard Miller 					return 0;
365*6e84dc96SRichard Miller 				if(t == 4)
366*6e84dc96SRichard Miller 					print("; %Dused+set and f=%d; return 0\n", v2, f);
367*6e84dc96SRichard Miller 				else
368*6e84dc96SRichard Miller 					print("; %Dused and f=%d; return 0\n", v2, f);
369*6e84dc96SRichard Miller 				return 0;
370*6e84dc96SRichard Miller 			}
371*6e84dc96SRichard Miller 			if(copyu(p, v2, v1)) {
372*6e84dc96SRichard Miller 				if(debug['P'])
373*6e84dc96SRichard Miller 					print("; sub fail; return 0\n");
374*6e84dc96SRichard Miller 				return 0;
375*6e84dc96SRichard Miller 			}
376*6e84dc96SRichard Miller 			if(debug['P'])
377*6e84dc96SRichard Miller 				print("; sub%D/%D", v2, v1);
378*6e84dc96SRichard Miller 			if(t == 4) {
379*6e84dc96SRichard Miller 				if(debug['P'])
380*6e84dc96SRichard Miller 					print("; %Dused+set; return 1\n", v2);
381*6e84dc96SRichard Miller 				return 1;
382*6e84dc96SRichard Miller 			}
383*6e84dc96SRichard Miller 			break;
384*6e84dc96SRichard Miller 		}
385*6e84dc96SRichard Miller 		if(!f) {
386*6e84dc96SRichard Miller 			t = copyu(p, v1, A);
387*6e84dc96SRichard Miller 			if(!f && (t == 2 || t == 3 || t == 4)) {
388*6e84dc96SRichard Miller 				f = 1;
389*6e84dc96SRichard Miller 				if(debug['P'])
390*6e84dc96SRichard Miller 					print("; %Dset and !f; f=%d", v1, f);
391*6e84dc96SRichard Miller 			}
392*6e84dc96SRichard Miller 		}
393*6e84dc96SRichard Miller 		if(debug['P'])
394*6e84dc96SRichard Miller 			print("\n");
395*6e84dc96SRichard Miller 		if(r->s2)
396*6e84dc96SRichard Miller 			if(!copy1(v1, v2, r->s2, f))
397*6e84dc96SRichard Miller 				return 0;
398*6e84dc96SRichard Miller 	}
399*6e84dc96SRichard Miller 	return 1;
400*6e84dc96SRichard Miller }
401*6e84dc96SRichard Miller 
402*6e84dc96SRichard Miller /*
403*6e84dc96SRichard Miller  * return
404*6e84dc96SRichard Miller  * 1 if v only used (and substitute),
405*6e84dc96SRichard Miller  * 2 if read-alter-rewrite
406*6e84dc96SRichard Miller  * 3 if set
407*6e84dc96SRichard Miller  * 4 if set and used
408*6e84dc96SRichard Miller  * 0 otherwise (not touched)
409*6e84dc96SRichard Miller  */
410*6e84dc96SRichard Miller int
copyu(Prog * p,Adr * v,Adr * s)411*6e84dc96SRichard Miller copyu(Prog *p, Adr *v, Adr *s)
412*6e84dc96SRichard Miller {
413*6e84dc96SRichard Miller 
414*6e84dc96SRichard Miller 	switch(p->as) {
415*6e84dc96SRichard Miller 
416*6e84dc96SRichard Miller 	default:
417*6e84dc96SRichard Miller 		if(debug['P'])
418*6e84dc96SRichard Miller 			print("unknown op %A\n", p->as);
419*6e84dc96SRichard Miller 		return 2;
420*6e84dc96SRichard Miller 
421*6e84dc96SRichard Miller 
422*6e84dc96SRichard Miller 	case ANOP:	/* read, write */
423*6e84dc96SRichard Miller 	case AMOVW:
424*6e84dc96SRichard Miller 	case AMOVWU:
425*6e84dc96SRichard Miller 	case AMOV:
426*6e84dc96SRichard Miller 	case AMOVF:
427*6e84dc96SRichard Miller 	case AMOVD:
428*6e84dc96SRichard Miller 	case AMOVH:
429*6e84dc96SRichard Miller 	case AMOVHU:
430*6e84dc96SRichard Miller 	case AMOVB:
431*6e84dc96SRichard Miller 	case AMOVBU:
432*6e84dc96SRichard Miller 	case AMOVDW:
433*6e84dc96SRichard Miller 	case AMOVWD:
434*6e84dc96SRichard Miller 	case AMOVUD:
435*6e84dc96SRichard Miller 	case AMOVFW:
436*6e84dc96SRichard Miller 	case AMOVWF:
437*6e84dc96SRichard Miller 	case AMOVUF:
438*6e84dc96SRichard Miller 	case AMOVFD:
439*6e84dc96SRichard Miller 	case AMOVDF:
440*6e84dc96SRichard Miller 		if(s != A) {
441*6e84dc96SRichard Miller 			if(copysub(&p->from, v, s, 1))
442*6e84dc96SRichard Miller 				return 1;
443*6e84dc96SRichard Miller 			if(!copyas(&p->to, v))
444*6e84dc96SRichard Miller 				if(copysub(&p->to, v, s, 1))
445*6e84dc96SRichard Miller 					return 1;
446*6e84dc96SRichard Miller 			return 0;
447*6e84dc96SRichard Miller 		}
448*6e84dc96SRichard Miller 		if(copyas(&p->to, v)) {
449*6e84dc96SRichard Miller 			if(copyau(&p->from, v))
450*6e84dc96SRichard Miller 				return 4;
451*6e84dc96SRichard Miller 			return 3;
452*6e84dc96SRichard Miller 		}
453*6e84dc96SRichard Miller 		if(copyau(&p->from, v))
454*6e84dc96SRichard Miller 			return 1;
455*6e84dc96SRichard Miller 		if(copyau(&p->to, v))
456*6e84dc96SRichard Miller 			return 1;
457*6e84dc96SRichard Miller 		return 0;
458*6e84dc96SRichard Miller 
459*6e84dc96SRichard Miller 	case ASLT:	/* read, read, write */
460*6e84dc96SRichard Miller 	case ASLTU:
461*6e84dc96SRichard Miller 	case ASGT:
462*6e84dc96SRichard Miller 	case ASGTU:
463*6e84dc96SRichard Miller 	case ACMPEQD:
464*6e84dc96SRichard Miller 	case ACMPEQF:
465*6e84dc96SRichard Miller 	case ACMPLED:
466*6e84dc96SRichard Miller 	case ACMPLEF:
467*6e84dc96SRichard Miller 	case ACMPLTD:
468*6e84dc96SRichard Miller 	case ACMPLTF:
469*6e84dc96SRichard Miller 
470*6e84dc96SRichard Miller 	case AADD:  case AADDW:
471*6e84dc96SRichard Miller 	case ASUB:  case ASUBW:
472*6e84dc96SRichard Miller 	case ASLL:  case ASLLW:
473*6e84dc96SRichard Miller 	case ASRL:  case ASRLW:
474*6e84dc96SRichard Miller 	case ASRA:  case ASRAW:
475*6e84dc96SRichard Miller 	case AOR:
476*6e84dc96SRichard Miller 	case AAND:
477*6e84dc96SRichard Miller 	case AXOR:
478*6e84dc96SRichard Miller 	case AMUL:  case AMULW:
479*6e84dc96SRichard Miller 	case ADIV:  case ADIVW:
480*6e84dc96SRichard Miller 	case ADIVU: case ADIVUW:
481*6e84dc96SRichard Miller 
482*6e84dc96SRichard Miller 	case AADDF:
483*6e84dc96SRichard Miller 	case AADDD:
484*6e84dc96SRichard Miller 	case ASUBF:
485*6e84dc96SRichard Miller 	case ASUBD:
486*6e84dc96SRichard Miller 	case AMULF:
487*6e84dc96SRichard Miller 	case AMULD:
488*6e84dc96SRichard Miller 	case ADIVF:
489*6e84dc96SRichard Miller 	case ADIVD:
490*6e84dc96SRichard Miller 		if(s != A) {
491*6e84dc96SRichard Miller 			if(copysub(&p->from, v, s, 1))
492*6e84dc96SRichard Miller 				return 1;
493*6e84dc96SRichard Miller 			if(copysub1(p, v, s, 1))
494*6e84dc96SRichard Miller 				return 1;
495*6e84dc96SRichard Miller 			if(!copyas(&p->to, v))
496*6e84dc96SRichard Miller 				if(copysub(&p->to, v, s, 1))
497*6e84dc96SRichard Miller 					return 1;
498*6e84dc96SRichard Miller 			return 0;
499*6e84dc96SRichard Miller 		}
500*6e84dc96SRichard Miller 		if(copyas(&p->to, v)) {
501*6e84dc96SRichard Miller 			if(p->reg == NREG)
502*6e84dc96SRichard Miller 				p->reg = p->to.reg;
503*6e84dc96SRichard Miller 			if(copyau(&p->from, v))
504*6e84dc96SRichard Miller 				return 4;
505*6e84dc96SRichard Miller 			if(copyau1(p, v))
506*6e84dc96SRichard Miller 				return 4;
507*6e84dc96SRichard Miller 			return 3;
508*6e84dc96SRichard Miller 		}
509*6e84dc96SRichard Miller 		if(copyau(&p->from, v))
510*6e84dc96SRichard Miller 			return 1;
511*6e84dc96SRichard Miller 		if(copyau1(p, v))
512*6e84dc96SRichard Miller 			return 1;
513*6e84dc96SRichard Miller 		if(copyau(&p->to, v))
514*6e84dc96SRichard Miller 			return 1;
515*6e84dc96SRichard Miller 		return 0;
516*6e84dc96SRichard Miller 
517*6e84dc96SRichard Miller 	case ABEQ:	/* read, read */
518*6e84dc96SRichard Miller 	case ABGE:
519*6e84dc96SRichard Miller 	case ABGEU:
520*6e84dc96SRichard Miller 	case ABLT:
521*6e84dc96SRichard Miller 	case ABLTU:
522*6e84dc96SRichard Miller 	case ABNE:
523*6e84dc96SRichard Miller 	case ABGT:
524*6e84dc96SRichard Miller 	case ABGTU:
525*6e84dc96SRichard Miller 	case ABLE:
526*6e84dc96SRichard Miller 	case ABLEU:
527*6e84dc96SRichard Miller 
528*6e84dc96SRichard Miller 		if(s != A) {
529*6e84dc96SRichard Miller 			if(copysub(&p->from, v, s, 1))
530*6e84dc96SRichard Miller 				return 1;
531*6e84dc96SRichard Miller 			return copysub1(p, v, s, 1);
532*6e84dc96SRichard Miller 		}
533*6e84dc96SRichard Miller 		if(copyau(&p->from, v))
534*6e84dc96SRichard Miller 			return 1;
535*6e84dc96SRichard Miller 		if(copyau1(p, v))
536*6e84dc96SRichard Miller 			return 1;
537*6e84dc96SRichard Miller 		return 0;
538*6e84dc96SRichard Miller 
539*6e84dc96SRichard Miller 	case AJMP:	/* funny */
540*6e84dc96SRichard Miller 		if(s != A) {
541*6e84dc96SRichard Miller 			if(copysub(&p->to, v, s, 1))
542*6e84dc96SRichard Miller 				return 1;
543*6e84dc96SRichard Miller 			return 0;
544*6e84dc96SRichard Miller 		}
545*6e84dc96SRichard Miller 		if(copyau(&p->to, v))
546*6e84dc96SRichard Miller 			return 1;
547*6e84dc96SRichard Miller 		return 0;
548*6e84dc96SRichard Miller 
549*6e84dc96SRichard Miller 	case ARET:	/* funny */
550*6e84dc96SRichard Miller 		if(v->type == D_REG)
551*6e84dc96SRichard Miller 		if(v->reg == REGRET)
552*6e84dc96SRichard Miller 			return 2;
553*6e84dc96SRichard Miller 		if(v->type == D_FREG)
554*6e84dc96SRichard Miller 		if(v->reg == FREGRET)
555*6e84dc96SRichard Miller 			return 2;
556*6e84dc96SRichard Miller 
557*6e84dc96SRichard Miller 	case AJAL:	/* funny */
558*6e84dc96SRichard Miller 		if(v->type == D_REG) {
559*6e84dc96SRichard Miller 			if(v->reg <= REGEXT && v->reg > exregoffset)
560*6e84dc96SRichard Miller 				return 2;
561*6e84dc96SRichard Miller 			if(REGARG && v->reg == REGARG)
562*6e84dc96SRichard Miller 				return 2;
563*6e84dc96SRichard Miller 		}
564*6e84dc96SRichard Miller 		if(v->type == D_FREG)
565*6e84dc96SRichard Miller 			if(v->reg <= FREGEXT && v->reg > exfregoffset)
566*6e84dc96SRichard Miller 				return 2;
567*6e84dc96SRichard Miller 
568*6e84dc96SRichard Miller 		if(s != A) {
569*6e84dc96SRichard Miller 			if(copysub(&p->to, v, s, 1))
570*6e84dc96SRichard Miller 				return 1;
571*6e84dc96SRichard Miller 			return 0;
572*6e84dc96SRichard Miller 		}
573*6e84dc96SRichard Miller 		if(copyau(&p->to, v))
574*6e84dc96SRichard Miller 			return 4;
575*6e84dc96SRichard Miller 		return 3;
576*6e84dc96SRichard Miller 
577*6e84dc96SRichard Miller 	case ATEXT:	/* funny */
578*6e84dc96SRichard Miller 		if(v->type == D_REG)
579*6e84dc96SRichard Miller 			if(v->reg == REGARG)
580*6e84dc96SRichard Miller 				return 3;
581*6e84dc96SRichard Miller 		return 0;
582*6e84dc96SRichard Miller 	}
583*6e84dc96SRichard Miller }
584*6e84dc96SRichard Miller 
585*6e84dc96SRichard Miller int
a2type(Prog * p)586*6e84dc96SRichard Miller a2type(Prog *p)
587*6e84dc96SRichard Miller {
588*6e84dc96SRichard Miller 
589*6e84dc96SRichard Miller 	switch(p->as) {
590*6e84dc96SRichard Miller 	case ABEQ:
591*6e84dc96SRichard Miller 	case ABGE:
592*6e84dc96SRichard Miller 	case ABGEU:
593*6e84dc96SRichard Miller 	case ABLT:
594*6e84dc96SRichard Miller 	case ABLTU:
595*6e84dc96SRichard Miller 	case ABNE:
596*6e84dc96SRichard Miller 	case ABGT:
597*6e84dc96SRichard Miller 	case ABGTU:
598*6e84dc96SRichard Miller 	case ABLE:
599*6e84dc96SRichard Miller 	case ABLEU:
600*6e84dc96SRichard Miller 
601*6e84dc96SRichard Miller 	case ASLT:
602*6e84dc96SRichard Miller 	case ASLTU:
603*6e84dc96SRichard Miller 	case ASGT:
604*6e84dc96SRichard Miller 	case ASGTU:
605*6e84dc96SRichard Miller 
606*6e84dc96SRichard Miller 	case AADD:  case AADDW:
607*6e84dc96SRichard Miller 	case ASUB:  case ASUBW:
608*6e84dc96SRichard Miller 	case ASLL:  case ASLLW:
609*6e84dc96SRichard Miller 	case ASRL:  case ASRLW:
610*6e84dc96SRichard Miller 	case ASRA:  case ASRAW:
611*6e84dc96SRichard Miller 	case AOR:
612*6e84dc96SRichard Miller 	case AAND:
613*6e84dc96SRichard Miller 	case AXOR:
614*6e84dc96SRichard Miller 	case AMUL:  case AMULW:
615*6e84dc96SRichard Miller 	case ADIV:  case ADIVW:
616*6e84dc96SRichard Miller 	case ADIVU: case ADIVUW:
617*6e84dc96SRichard Miller 		return D_REG;
618*6e84dc96SRichard Miller 
619*6e84dc96SRichard Miller 	case ACMPEQD:
620*6e84dc96SRichard Miller 	case ACMPEQF:
621*6e84dc96SRichard Miller 	case ACMPLED:
622*6e84dc96SRichard Miller 	case ACMPLEF:
623*6e84dc96SRichard Miller 	case ACMPLTD:
624*6e84dc96SRichard Miller 	case ACMPLTF:
625*6e84dc96SRichard Miller 
626*6e84dc96SRichard Miller 	case AADDF:
627*6e84dc96SRichard Miller 	case AADDD:
628*6e84dc96SRichard Miller 	case ASUBF:
629*6e84dc96SRichard Miller 	case ASUBD:
630*6e84dc96SRichard Miller 	case AMULF:
631*6e84dc96SRichard Miller 	case AMULD:
632*6e84dc96SRichard Miller 	case ADIVF:
633*6e84dc96SRichard Miller 	case ADIVD:
634*6e84dc96SRichard Miller 		return D_FREG;
635*6e84dc96SRichard Miller 	}
636*6e84dc96SRichard Miller 	return D_NONE;
637*6e84dc96SRichard Miller }
638*6e84dc96SRichard Miller 
639*6e84dc96SRichard Miller /*
640*6e84dc96SRichard Miller  * direct reference,
641*6e84dc96SRichard Miller  * could be set/use depending on
642*6e84dc96SRichard Miller  * semantics
643*6e84dc96SRichard Miller  */
644*6e84dc96SRichard Miller int
copyas(Adr * a,Adr * v)645*6e84dc96SRichard Miller copyas(Adr *a, Adr *v)
646*6e84dc96SRichard Miller {
647*6e84dc96SRichard Miller 
648*6e84dc96SRichard Miller 	if(regtyp(v))
649*6e84dc96SRichard Miller 		if(a->type == v->type)
650*6e84dc96SRichard Miller 		if(a->reg == v->reg)
651*6e84dc96SRichard Miller 			return 1;
652*6e84dc96SRichard Miller 	return 0;
653*6e84dc96SRichard Miller }
654*6e84dc96SRichard Miller 
655*6e84dc96SRichard Miller /*
656*6e84dc96SRichard Miller  * either direct or indirect
657*6e84dc96SRichard Miller  */
658*6e84dc96SRichard Miller int
copyau(Adr * a,Adr * v)659*6e84dc96SRichard Miller copyau(Adr *a, Adr *v)
660*6e84dc96SRichard Miller {
661*6e84dc96SRichard Miller 
662*6e84dc96SRichard Miller 	if(copyas(a, v))
663*6e84dc96SRichard Miller 		return 1;
664*6e84dc96SRichard Miller 	if(v->type == D_REG)
665*6e84dc96SRichard Miller 		if(a->type == D_OREG)
666*6e84dc96SRichard Miller 			if(v->reg == a->reg)
667*6e84dc96SRichard Miller 				return 1;
668*6e84dc96SRichard Miller 	return 0;
669*6e84dc96SRichard Miller }
670*6e84dc96SRichard Miller 
671*6e84dc96SRichard Miller int
copyau1(Prog * p,Adr * v)672*6e84dc96SRichard Miller copyau1(Prog *p, Adr *v)
673*6e84dc96SRichard Miller {
674*6e84dc96SRichard Miller 
675*6e84dc96SRichard Miller 	if(regtyp(v))
676*6e84dc96SRichard Miller 		if(p->from.type == v->type || p->to.type == v->type)
677*6e84dc96SRichard Miller 		if(p->reg == v->reg) {
678*6e84dc96SRichard Miller 			if(a2type(p) == v->type)
679*6e84dc96SRichard Miller 				return 1;
680*6e84dc96SRichard Miller 		}
681*6e84dc96SRichard Miller 	return 0;
682*6e84dc96SRichard Miller }
683*6e84dc96SRichard Miller 
684*6e84dc96SRichard Miller /*
685*6e84dc96SRichard Miller  * substitute s for v in a
686*6e84dc96SRichard Miller  * return failure to substitute
687*6e84dc96SRichard Miller  */
688*6e84dc96SRichard Miller int
copysub(Adr * a,Adr * v,Adr * s,int f)689*6e84dc96SRichard Miller copysub(Adr *a, Adr *v, Adr *s, int f)
690*6e84dc96SRichard Miller {
691*6e84dc96SRichard Miller 
692*6e84dc96SRichard Miller 	if(f)
693*6e84dc96SRichard Miller 	if(copyau(a, v))
694*6e84dc96SRichard Miller 		a->reg = s->reg;
695*6e84dc96SRichard Miller 	return 0;
696*6e84dc96SRichard Miller }
697*6e84dc96SRichard Miller 
698*6e84dc96SRichard Miller int
copysub1(Prog * p1,Adr * v,Adr * s,int f)699*6e84dc96SRichard Miller copysub1(Prog *p1, Adr *v, Adr *s, int f)
700*6e84dc96SRichard Miller {
701*6e84dc96SRichard Miller 
702*6e84dc96SRichard Miller 	if(f)
703*6e84dc96SRichard Miller 	if(copyau1(p1, v))
704*6e84dc96SRichard Miller 		p1->reg = s->reg;
705*6e84dc96SRichard Miller 	return 0;
706*6e84dc96SRichard Miller }
707