xref: /inferno-os/utils/6c/peep.c (revision b370703f35244a5152bf72daf6a871fba74ed373)
1*b370703fSCharles.Forsyth #include "gc.h"
2*b370703fSCharles.Forsyth 
3*b370703fSCharles.Forsyth static int
needc(Prog * p)4*b370703fSCharles.Forsyth needc(Prog *p)
5*b370703fSCharles.Forsyth {
6*b370703fSCharles.Forsyth 	while(p != P) {
7*b370703fSCharles.Forsyth 		switch(p->as) {
8*b370703fSCharles.Forsyth 		case AADCL:
9*b370703fSCharles.Forsyth 		case AADCQ:
10*b370703fSCharles.Forsyth 		case ASBBL:
11*b370703fSCharles.Forsyth 		case ASBBQ:
12*b370703fSCharles.Forsyth 		case ARCRL:
13*b370703fSCharles.Forsyth 		case ARCRQ:
14*b370703fSCharles.Forsyth 			return 1;
15*b370703fSCharles.Forsyth 		case AADDL:
16*b370703fSCharles.Forsyth 		case AADDQ:
17*b370703fSCharles.Forsyth 		case ASUBL:
18*b370703fSCharles.Forsyth 		case ASUBQ:
19*b370703fSCharles.Forsyth 		case AJMP:
20*b370703fSCharles.Forsyth 		case ARET:
21*b370703fSCharles.Forsyth 		case ACALL:
22*b370703fSCharles.Forsyth 			return 0;
23*b370703fSCharles.Forsyth 		default:
24*b370703fSCharles.Forsyth 			if(p->to.type == D_BRANCH)
25*b370703fSCharles.Forsyth 				return 0;
26*b370703fSCharles.Forsyth 		}
27*b370703fSCharles.Forsyth 		p = p->link;
28*b370703fSCharles.Forsyth 	}
29*b370703fSCharles.Forsyth 	return 0;
30*b370703fSCharles.Forsyth }
31*b370703fSCharles.Forsyth 
32*b370703fSCharles.Forsyth static Reg*
rnops(Reg * r)33*b370703fSCharles.Forsyth rnops(Reg *r)
34*b370703fSCharles.Forsyth {
35*b370703fSCharles.Forsyth 	Prog *p;
36*b370703fSCharles.Forsyth 	Reg *r1;
37*b370703fSCharles.Forsyth 
38*b370703fSCharles.Forsyth 	if(r != R)
39*b370703fSCharles.Forsyth 	for(;;){
40*b370703fSCharles.Forsyth 		p = r->prog;
41*b370703fSCharles.Forsyth 		if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
42*b370703fSCharles.Forsyth 			break;
43*b370703fSCharles.Forsyth 		r1 = uniqs(r);
44*b370703fSCharles.Forsyth 		if(r1 == R)
45*b370703fSCharles.Forsyth 			break;
46*b370703fSCharles.Forsyth 		r = r1;
47*b370703fSCharles.Forsyth 	}
48*b370703fSCharles.Forsyth 	return r;
49*b370703fSCharles.Forsyth }
50*b370703fSCharles.Forsyth 
51*b370703fSCharles.Forsyth void
peep(void)52*b370703fSCharles.Forsyth peep(void)
53*b370703fSCharles.Forsyth {
54*b370703fSCharles.Forsyth 	Reg *r, *r1, *r2;
55*b370703fSCharles.Forsyth 	Prog *p, *p1;
56*b370703fSCharles.Forsyth 	int t;
57*b370703fSCharles.Forsyth 
58*b370703fSCharles.Forsyth 	/*
59*b370703fSCharles.Forsyth 	 * complete R structure
60*b370703fSCharles.Forsyth 	 */
61*b370703fSCharles.Forsyth 	t = 0;
62*b370703fSCharles.Forsyth 	for(r=firstr; r!=R; r=r1) {
63*b370703fSCharles.Forsyth 		r1 = r->link;
64*b370703fSCharles.Forsyth 		if(r1 == R)
65*b370703fSCharles.Forsyth 			break;
66*b370703fSCharles.Forsyth 		p = r->prog->link;
67*b370703fSCharles.Forsyth 		while(p != r1->prog)
68*b370703fSCharles.Forsyth 		switch(p->as) {
69*b370703fSCharles.Forsyth 		default:
70*b370703fSCharles.Forsyth 			r2 = rega();
71*b370703fSCharles.Forsyth 			r->link = r2;
72*b370703fSCharles.Forsyth 			r2->link = r1;
73*b370703fSCharles.Forsyth 
74*b370703fSCharles.Forsyth 			r2->prog = p;
75*b370703fSCharles.Forsyth 			r2->p1 = r;
76*b370703fSCharles.Forsyth 			r->s1 = r2;
77*b370703fSCharles.Forsyth 			r2->s1 = r1;
78*b370703fSCharles.Forsyth 			r1->p1 = r2;
79*b370703fSCharles.Forsyth 
80*b370703fSCharles.Forsyth 			r = r2;
81*b370703fSCharles.Forsyth 			t++;
82*b370703fSCharles.Forsyth 
83*b370703fSCharles.Forsyth 		case ADATA:
84*b370703fSCharles.Forsyth 		case AGLOBL:
85*b370703fSCharles.Forsyth 		case ANAME:
86*b370703fSCharles.Forsyth 		case ASIGNAME:
87*b370703fSCharles.Forsyth 			p = p->link;
88*b370703fSCharles.Forsyth 		}
89*b370703fSCharles.Forsyth 	}
90*b370703fSCharles.Forsyth 
91*b370703fSCharles.Forsyth 	pc = 0;	/* speculating it won't kill */
92*b370703fSCharles.Forsyth 
93*b370703fSCharles.Forsyth loop1:
94*b370703fSCharles.Forsyth 
95*b370703fSCharles.Forsyth 	t = 0;
96*b370703fSCharles.Forsyth 	for(r=firstr; r!=R; r=r->link) {
97*b370703fSCharles.Forsyth 		p = r->prog;
98*b370703fSCharles.Forsyth 		switch(p->as) {
99*b370703fSCharles.Forsyth 		case AMOVL:
100*b370703fSCharles.Forsyth 		case AMOVQ:
101*b370703fSCharles.Forsyth 		case AMOVSS:
102*b370703fSCharles.Forsyth 		case AMOVSD:
103*b370703fSCharles.Forsyth 			if(regtyp(&p->to))
104*b370703fSCharles.Forsyth 			if(regtyp(&p->from)) {
105*b370703fSCharles.Forsyth 				if(copyprop(r)) {
106*b370703fSCharles.Forsyth 					excise(r);
107*b370703fSCharles.Forsyth 					t++;
108*b370703fSCharles.Forsyth 				} else
109*b370703fSCharles.Forsyth 				if(subprop(r) && copyprop(r)) {
110*b370703fSCharles.Forsyth 					excise(r);
111*b370703fSCharles.Forsyth 					t++;
112*b370703fSCharles.Forsyth 				}
113*b370703fSCharles.Forsyth 			}
114*b370703fSCharles.Forsyth 			break;
115*b370703fSCharles.Forsyth 
116*b370703fSCharles.Forsyth 		case AMOVBLZX:
117*b370703fSCharles.Forsyth 		case AMOVWLZX:
118*b370703fSCharles.Forsyth 		case AMOVBLSX:
119*b370703fSCharles.Forsyth 		case AMOVWLSX:
120*b370703fSCharles.Forsyth 			if(regtyp(&p->to)) {
121*b370703fSCharles.Forsyth 				r1 = rnops(uniqs(r));
122*b370703fSCharles.Forsyth 				if(r1 != R) {
123*b370703fSCharles.Forsyth 					p1 = r1->prog;
124*b370703fSCharles.Forsyth 					if(p->as == p1->as && p->to.type == p1->from.type){
125*b370703fSCharles.Forsyth 						p1->as = AMOVL;
126*b370703fSCharles.Forsyth 						t++;
127*b370703fSCharles.Forsyth 					}
128*b370703fSCharles.Forsyth 				}
129*b370703fSCharles.Forsyth 			}
130*b370703fSCharles.Forsyth 			break;
131*b370703fSCharles.Forsyth 
132*b370703fSCharles.Forsyth 		case AMOVBQSX:
133*b370703fSCharles.Forsyth 		case AMOVBQZX:
134*b370703fSCharles.Forsyth 		case AMOVWQSX:
135*b370703fSCharles.Forsyth 		case AMOVWQZX:
136*b370703fSCharles.Forsyth 		case AMOVLQSX:
137*b370703fSCharles.Forsyth 		case AMOVLQZX:
138*b370703fSCharles.Forsyth 			if(regtyp(&p->to)) {
139*b370703fSCharles.Forsyth 				r1 = rnops(uniqs(r));
140*b370703fSCharles.Forsyth 				if(r1 != R) {
141*b370703fSCharles.Forsyth 					p1 = r1->prog;
142*b370703fSCharles.Forsyth 					if(p->as == p1->as && p->to.type == p1->from.type){
143*b370703fSCharles.Forsyth 						p1->as = AMOVQ;
144*b370703fSCharles.Forsyth 						t++;
145*b370703fSCharles.Forsyth 					}
146*b370703fSCharles.Forsyth 				}
147*b370703fSCharles.Forsyth 			}
148*b370703fSCharles.Forsyth 			break;
149*b370703fSCharles.Forsyth 
150*b370703fSCharles.Forsyth 		case AADDL:
151*b370703fSCharles.Forsyth 		case AADDQ:
152*b370703fSCharles.Forsyth 		case AADDW:
153*b370703fSCharles.Forsyth 			if(p->from.type != D_CONST || needc(p->link))
154*b370703fSCharles.Forsyth 				break;
155*b370703fSCharles.Forsyth 			if(p->from.offset == -1){
156*b370703fSCharles.Forsyth 				if(p->as == AADDQ)
157*b370703fSCharles.Forsyth 					p->as = ADECQ;
158*b370703fSCharles.Forsyth 				else if(p->as == AADDL)
159*b370703fSCharles.Forsyth 					p->as = ADECL;
160*b370703fSCharles.Forsyth 				else
161*b370703fSCharles.Forsyth 					p->as = ADECW;
162*b370703fSCharles.Forsyth 				p->from = zprog.from;
163*b370703fSCharles.Forsyth 			}
164*b370703fSCharles.Forsyth 			else if(p->from.offset == 1){
165*b370703fSCharles.Forsyth 				if(p->as == AADDQ)
166*b370703fSCharles.Forsyth 					p->as = AINCQ;
167*b370703fSCharles.Forsyth 				else if(p->as == AADDL)
168*b370703fSCharles.Forsyth 					p->as = AINCL;
169*b370703fSCharles.Forsyth 				else
170*b370703fSCharles.Forsyth 					p->as = AINCW;
171*b370703fSCharles.Forsyth 				p->from = zprog.from;
172*b370703fSCharles.Forsyth 			}
173*b370703fSCharles.Forsyth 			break;
174*b370703fSCharles.Forsyth 
175*b370703fSCharles.Forsyth 		case ASUBL:
176*b370703fSCharles.Forsyth 		case ASUBQ:
177*b370703fSCharles.Forsyth 		case ASUBW:
178*b370703fSCharles.Forsyth 			if(p->from.type != D_CONST || needc(p->link))
179*b370703fSCharles.Forsyth 				break;
180*b370703fSCharles.Forsyth 			if(p->from.offset == -1) {
181*b370703fSCharles.Forsyth 				if(p->as == ASUBQ)
182*b370703fSCharles.Forsyth 					p->as = AINCQ;
183*b370703fSCharles.Forsyth 				else if(p->as == ASUBL)
184*b370703fSCharles.Forsyth 					p->as = AINCL;
185*b370703fSCharles.Forsyth 				else
186*b370703fSCharles.Forsyth 					p->as = AINCW;
187*b370703fSCharles.Forsyth 				p->from = zprog.from;
188*b370703fSCharles.Forsyth 			}
189*b370703fSCharles.Forsyth 			else if(p->from.offset == 1){
190*b370703fSCharles.Forsyth 				if(p->as == ASUBQ)
191*b370703fSCharles.Forsyth 					p->as = ADECQ;
192*b370703fSCharles.Forsyth 				else if(p->as == ASUBL)
193*b370703fSCharles.Forsyth 					p->as = ADECL;
194*b370703fSCharles.Forsyth 				else
195*b370703fSCharles.Forsyth 					p->as = ADECW;
196*b370703fSCharles.Forsyth 				p->from = zprog.from;
197*b370703fSCharles.Forsyth 			}
198*b370703fSCharles.Forsyth 			break;
199*b370703fSCharles.Forsyth 		}
200*b370703fSCharles.Forsyth 	}
201*b370703fSCharles.Forsyth 	if(t)
202*b370703fSCharles.Forsyth 		goto loop1;
203*b370703fSCharles.Forsyth }
204*b370703fSCharles.Forsyth 
205*b370703fSCharles.Forsyth void
excise(Reg * r)206*b370703fSCharles.Forsyth excise(Reg *r)
207*b370703fSCharles.Forsyth {
208*b370703fSCharles.Forsyth 	Prog *p;
209*b370703fSCharles.Forsyth 
210*b370703fSCharles.Forsyth 	p = r->prog;
211*b370703fSCharles.Forsyth 	p->as = ANOP;
212*b370703fSCharles.Forsyth 	p->from = zprog.from;
213*b370703fSCharles.Forsyth 	p->to = zprog.to;
214*b370703fSCharles.Forsyth }
215*b370703fSCharles.Forsyth 
216*b370703fSCharles.Forsyth Reg*
uniqp(Reg * r)217*b370703fSCharles.Forsyth uniqp(Reg *r)
218*b370703fSCharles.Forsyth {
219*b370703fSCharles.Forsyth 	Reg *r1;
220*b370703fSCharles.Forsyth 
221*b370703fSCharles.Forsyth 	r1 = r->p1;
222*b370703fSCharles.Forsyth 	if(r1 == R) {
223*b370703fSCharles.Forsyth 		r1 = r->p2;
224*b370703fSCharles.Forsyth 		if(r1 == R || r1->p2link != R)
225*b370703fSCharles.Forsyth 			return R;
226*b370703fSCharles.Forsyth 	} else
227*b370703fSCharles.Forsyth 		if(r->p2 != R)
228*b370703fSCharles.Forsyth 			return R;
229*b370703fSCharles.Forsyth 	return r1;
230*b370703fSCharles.Forsyth }
231*b370703fSCharles.Forsyth 
232*b370703fSCharles.Forsyth Reg*
uniqs(Reg * r)233*b370703fSCharles.Forsyth uniqs(Reg *r)
234*b370703fSCharles.Forsyth {
235*b370703fSCharles.Forsyth 	Reg *r1;
236*b370703fSCharles.Forsyth 
237*b370703fSCharles.Forsyth 	r1 = r->s1;
238*b370703fSCharles.Forsyth 	if(r1 == R) {
239*b370703fSCharles.Forsyth 		r1 = r->s2;
240*b370703fSCharles.Forsyth 		if(r1 == R)
241*b370703fSCharles.Forsyth 			return R;
242*b370703fSCharles.Forsyth 	} else
243*b370703fSCharles.Forsyth 		if(r->s2 != R)
244*b370703fSCharles.Forsyth 			return R;
245*b370703fSCharles.Forsyth 	return r1;
246*b370703fSCharles.Forsyth }
247*b370703fSCharles.Forsyth 
248*b370703fSCharles.Forsyth int
regtyp(Adr * a)249*b370703fSCharles.Forsyth regtyp(Adr *a)
250*b370703fSCharles.Forsyth {
251*b370703fSCharles.Forsyth 	int t;
252*b370703fSCharles.Forsyth 
253*b370703fSCharles.Forsyth 	t = a->type;
254*b370703fSCharles.Forsyth 	if(t >= D_AX && t <= D_R15)
255*b370703fSCharles.Forsyth 		return 1;
256*b370703fSCharles.Forsyth 	if(t >= D_X0 && t <= D_X0+15)
257*b370703fSCharles.Forsyth 		return 1;
258*b370703fSCharles.Forsyth 	return 0;
259*b370703fSCharles.Forsyth }
260*b370703fSCharles.Forsyth 
261*b370703fSCharles.Forsyth /*
262*b370703fSCharles.Forsyth  * the idea is to substitute
263*b370703fSCharles.Forsyth  * one register for another
264*b370703fSCharles.Forsyth  * from one MOV to another
265*b370703fSCharles.Forsyth  *	MOV	a, R0
266*b370703fSCharles.Forsyth  *	ADD	b, R0	/ no use of R1
267*b370703fSCharles.Forsyth  *	MOV	R0, R1
268*b370703fSCharles.Forsyth  * would be converted to
269*b370703fSCharles.Forsyth  *	MOV	a, R1
270*b370703fSCharles.Forsyth  *	ADD	b, R1
271*b370703fSCharles.Forsyth  *	MOV	R1, R0
272*b370703fSCharles.Forsyth  * hopefully, then the former or latter MOV
273*b370703fSCharles.Forsyth  * will be eliminated by copy propagation.
274*b370703fSCharles.Forsyth  */
275*b370703fSCharles.Forsyth int
subprop(Reg * r0)276*b370703fSCharles.Forsyth subprop(Reg *r0)
277*b370703fSCharles.Forsyth {
278*b370703fSCharles.Forsyth 	Prog *p;
279*b370703fSCharles.Forsyth 	Adr *v1, *v2;
280*b370703fSCharles.Forsyth 	Reg *r;
281*b370703fSCharles.Forsyth 	int t;
282*b370703fSCharles.Forsyth 
283*b370703fSCharles.Forsyth 	p = r0->prog;
284*b370703fSCharles.Forsyth 	v1 = &p->from;
285*b370703fSCharles.Forsyth 	if(!regtyp(v1))
286*b370703fSCharles.Forsyth 		return 0;
287*b370703fSCharles.Forsyth 	v2 = &p->to;
288*b370703fSCharles.Forsyth 	if(!regtyp(v2))
289*b370703fSCharles.Forsyth 		return 0;
290*b370703fSCharles.Forsyth 	for(r=uniqp(r0); r!=R; r=uniqp(r)) {
291*b370703fSCharles.Forsyth 		if(uniqs(r) == R)
292*b370703fSCharles.Forsyth 			break;
293*b370703fSCharles.Forsyth 		p = r->prog;
294*b370703fSCharles.Forsyth 		switch(p->as) {
295*b370703fSCharles.Forsyth 		case ACALL:
296*b370703fSCharles.Forsyth 			return 0;
297*b370703fSCharles.Forsyth 
298*b370703fSCharles.Forsyth 		case AIMULL:
299*b370703fSCharles.Forsyth 		case AIMULQ:
300*b370703fSCharles.Forsyth 		case AIMULW:
301*b370703fSCharles.Forsyth 			if(p->to.type != D_NONE)
302*b370703fSCharles.Forsyth 				break;
303*b370703fSCharles.Forsyth 
304*b370703fSCharles.Forsyth 		case ADIVB:
305*b370703fSCharles.Forsyth 		case ADIVL:
306*b370703fSCharles.Forsyth 		case ADIVQ:
307*b370703fSCharles.Forsyth 		case ADIVW:
308*b370703fSCharles.Forsyth 		case AIDIVB:
309*b370703fSCharles.Forsyth 		case AIDIVL:
310*b370703fSCharles.Forsyth 		case AIDIVQ:
311*b370703fSCharles.Forsyth 		case AIDIVW:
312*b370703fSCharles.Forsyth 		case AIMULB:
313*b370703fSCharles.Forsyth 		case AMULB:
314*b370703fSCharles.Forsyth 		case AMULL:
315*b370703fSCharles.Forsyth 		case AMULQ:
316*b370703fSCharles.Forsyth 		case AMULW:
317*b370703fSCharles.Forsyth 
318*b370703fSCharles.Forsyth 		case AROLB:
319*b370703fSCharles.Forsyth 		case AROLL:
320*b370703fSCharles.Forsyth 		case AROLQ:
321*b370703fSCharles.Forsyth 		case AROLW:
322*b370703fSCharles.Forsyth 		case ARORB:
323*b370703fSCharles.Forsyth 		case ARORL:
324*b370703fSCharles.Forsyth 		case ARORQ:
325*b370703fSCharles.Forsyth 		case ARORW:
326*b370703fSCharles.Forsyth 		case ASALB:
327*b370703fSCharles.Forsyth 		case ASALL:
328*b370703fSCharles.Forsyth 		case ASALQ:
329*b370703fSCharles.Forsyth 		case ASALW:
330*b370703fSCharles.Forsyth 		case ASARB:
331*b370703fSCharles.Forsyth 		case ASARL:
332*b370703fSCharles.Forsyth 		case ASARQ:
333*b370703fSCharles.Forsyth 		case ASARW:
334*b370703fSCharles.Forsyth 		case ASHLB:
335*b370703fSCharles.Forsyth 		case ASHLL:
336*b370703fSCharles.Forsyth 		case ASHLQ:
337*b370703fSCharles.Forsyth 		case ASHLW:
338*b370703fSCharles.Forsyth 		case ASHRB:
339*b370703fSCharles.Forsyth 		case ASHRL:
340*b370703fSCharles.Forsyth 		case ASHRQ:
341*b370703fSCharles.Forsyth 		case ASHRW:
342*b370703fSCharles.Forsyth 
343*b370703fSCharles.Forsyth 		case AREP:
344*b370703fSCharles.Forsyth 		case AREPN:
345*b370703fSCharles.Forsyth 
346*b370703fSCharles.Forsyth 		case ACWD:
347*b370703fSCharles.Forsyth 		case ACDQ:
348*b370703fSCharles.Forsyth 		case ACQO:
349*b370703fSCharles.Forsyth 
350*b370703fSCharles.Forsyth 		case AMOVSL:
351*b370703fSCharles.Forsyth 		case AMOVSQ:
352*b370703fSCharles.Forsyth 			return 0;
353*b370703fSCharles.Forsyth 
354*b370703fSCharles.Forsyth 		case AMOVL:
355*b370703fSCharles.Forsyth 		case AMOVQ:
356*b370703fSCharles.Forsyth 			if(p->to.type == v1->type)
357*b370703fSCharles.Forsyth 				goto gotit;
358*b370703fSCharles.Forsyth 			break;
359*b370703fSCharles.Forsyth 		}
360*b370703fSCharles.Forsyth 		if(copyau(&p->from, v2) ||
361*b370703fSCharles.Forsyth 		   copyau(&p->to, v2))
362*b370703fSCharles.Forsyth 			break;
363*b370703fSCharles.Forsyth 		if(copysub(&p->from, v1, v2, 0) ||
364*b370703fSCharles.Forsyth 		   copysub(&p->to, v1, v2, 0))
365*b370703fSCharles.Forsyth 			break;
366*b370703fSCharles.Forsyth 	}
367*b370703fSCharles.Forsyth 	return 0;
368*b370703fSCharles.Forsyth 
369*b370703fSCharles.Forsyth gotit:
370*b370703fSCharles.Forsyth 	copysub(&p->to, v1, v2, 1);
371*b370703fSCharles.Forsyth 	if(debug['P']) {
372*b370703fSCharles.Forsyth 		print("gotit: %D->%D\n%P", v1, v2, r->prog);
373*b370703fSCharles.Forsyth 		if(p->from.type == v2->type)
374*b370703fSCharles.Forsyth 			print(" excise");
375*b370703fSCharles.Forsyth 		print("\n");
376*b370703fSCharles.Forsyth 	}
377*b370703fSCharles.Forsyth 	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
378*b370703fSCharles.Forsyth 		p = r->prog;
379*b370703fSCharles.Forsyth 		copysub(&p->from, v1, v2, 1);
380*b370703fSCharles.Forsyth 		copysub(&p->to, v1, v2, 1);
381*b370703fSCharles.Forsyth 		if(debug['P'])
382*b370703fSCharles.Forsyth 			print("%P\n", r->prog);
383*b370703fSCharles.Forsyth 	}
384*b370703fSCharles.Forsyth 	t = v1->type;
385*b370703fSCharles.Forsyth 	v1->type = v2->type;
386*b370703fSCharles.Forsyth 	v2->type = t;
387*b370703fSCharles.Forsyth 	if(debug['P'])
388*b370703fSCharles.Forsyth 		print("%P last\n", r->prog);
389*b370703fSCharles.Forsyth 	return 1;
390*b370703fSCharles.Forsyth }
391*b370703fSCharles.Forsyth 
392*b370703fSCharles.Forsyth /*
393*b370703fSCharles.Forsyth  * The idea is to remove redundant copies.
394*b370703fSCharles.Forsyth  *	v1->v2	F=0
395*b370703fSCharles.Forsyth  *	(use v2	s/v2/v1/)*
396*b370703fSCharles.Forsyth  *	set v1	F=1
397*b370703fSCharles.Forsyth  *	use v2	return fail
398*b370703fSCharles.Forsyth  *	-----------------
399*b370703fSCharles.Forsyth  *	v1->v2	F=0
400*b370703fSCharles.Forsyth  *	(use v2	s/v2/v1/)*
401*b370703fSCharles.Forsyth  *	set v1	F=1
402*b370703fSCharles.Forsyth  *	set v2	return success
403*b370703fSCharles.Forsyth  */
404*b370703fSCharles.Forsyth int
copyprop(Reg * r0)405*b370703fSCharles.Forsyth copyprop(Reg *r0)
406*b370703fSCharles.Forsyth {
407*b370703fSCharles.Forsyth 	Prog *p;
408*b370703fSCharles.Forsyth 	Adr *v1, *v2;
409*b370703fSCharles.Forsyth 	Reg *r;
410*b370703fSCharles.Forsyth 
411*b370703fSCharles.Forsyth 	p = r0->prog;
412*b370703fSCharles.Forsyth 	v1 = &p->from;
413*b370703fSCharles.Forsyth 	v2 = &p->to;
414*b370703fSCharles.Forsyth 	if(copyas(v1, v2))
415*b370703fSCharles.Forsyth 		return 1;
416*b370703fSCharles.Forsyth 	for(r=firstr; r!=R; r=r->link)
417*b370703fSCharles.Forsyth 		r->active = 0;
418*b370703fSCharles.Forsyth 	return copy1(v1, v2, r0->s1, 0);
419*b370703fSCharles.Forsyth }
420*b370703fSCharles.Forsyth 
421*b370703fSCharles.Forsyth int
copy1(Adr * v1,Adr * v2,Reg * r,int f)422*b370703fSCharles.Forsyth copy1(Adr *v1, Adr *v2, Reg *r, int f)
423*b370703fSCharles.Forsyth {
424*b370703fSCharles.Forsyth 	int t;
425*b370703fSCharles.Forsyth 	Prog *p;
426*b370703fSCharles.Forsyth 
427*b370703fSCharles.Forsyth 	if(r->active) {
428*b370703fSCharles.Forsyth 		if(debug['P'])
429*b370703fSCharles.Forsyth 			print("act set; return 1\n");
430*b370703fSCharles.Forsyth 		return 1;
431*b370703fSCharles.Forsyth 	}
432*b370703fSCharles.Forsyth 	r->active = 1;
433*b370703fSCharles.Forsyth 	if(debug['P'])
434*b370703fSCharles.Forsyth 		print("copy %D->%D f=%d\n", v1, v2, f);
435*b370703fSCharles.Forsyth 	for(; r != R; r = r->s1) {
436*b370703fSCharles.Forsyth 		p = r->prog;
437*b370703fSCharles.Forsyth 		if(debug['P'])
438*b370703fSCharles.Forsyth 			print("%P", p);
439*b370703fSCharles.Forsyth 		if(!f && uniqp(r) == R) {
440*b370703fSCharles.Forsyth 			f = 1;
441*b370703fSCharles.Forsyth 			if(debug['P'])
442*b370703fSCharles.Forsyth 				print("; merge; f=%d", f);
443*b370703fSCharles.Forsyth 		}
444*b370703fSCharles.Forsyth 		t = copyu(p, v2, A);
445*b370703fSCharles.Forsyth 		switch(t) {
446*b370703fSCharles.Forsyth 		case 2:	/* rar, cant split */
447*b370703fSCharles.Forsyth 			if(debug['P'])
448*b370703fSCharles.Forsyth 				print("; %D rar; return 0\n", v2);
449*b370703fSCharles.Forsyth 			return 0;
450*b370703fSCharles.Forsyth 
451*b370703fSCharles.Forsyth 		case 3:	/* set */
452*b370703fSCharles.Forsyth 			if(debug['P'])
453*b370703fSCharles.Forsyth 				print("; %D set; return 1\n", v2);
454*b370703fSCharles.Forsyth 			return 1;
455*b370703fSCharles.Forsyth 
456*b370703fSCharles.Forsyth 		case 1:	/* used, substitute */
457*b370703fSCharles.Forsyth 		case 4:	/* use and set */
458*b370703fSCharles.Forsyth 			if(f) {
459*b370703fSCharles.Forsyth 				if(!debug['P'])
460*b370703fSCharles.Forsyth 					return 0;
461*b370703fSCharles.Forsyth 				if(t == 4)
462*b370703fSCharles.Forsyth 					print("; %D used+set and f=%d; return 0\n", v2, f);
463*b370703fSCharles.Forsyth 				else
464*b370703fSCharles.Forsyth 					print("; %D used and f=%d; return 0\n", v2, f);
465*b370703fSCharles.Forsyth 				return 0;
466*b370703fSCharles.Forsyth 			}
467*b370703fSCharles.Forsyth 			if(copyu(p, v2, v1)) {
468*b370703fSCharles.Forsyth 				if(debug['P'])
469*b370703fSCharles.Forsyth 					print("; sub fail; return 0\n");
470*b370703fSCharles.Forsyth 				return 0;
471*b370703fSCharles.Forsyth 			}
472*b370703fSCharles.Forsyth 			if(debug['P'])
473*b370703fSCharles.Forsyth 				print("; sub %D/%D", v2, v1);
474*b370703fSCharles.Forsyth 			if(t == 4) {
475*b370703fSCharles.Forsyth 				if(debug['P'])
476*b370703fSCharles.Forsyth 					print("; %D used+set; return 1\n", v2);
477*b370703fSCharles.Forsyth 				return 1;
478*b370703fSCharles.Forsyth 			}
479*b370703fSCharles.Forsyth 			break;
480*b370703fSCharles.Forsyth 		}
481*b370703fSCharles.Forsyth 		if(!f) {
482*b370703fSCharles.Forsyth 			t = copyu(p, v1, A);
483*b370703fSCharles.Forsyth 			if(!f && (t == 2 || t == 3 || t == 4)) {
484*b370703fSCharles.Forsyth 				f = 1;
485*b370703fSCharles.Forsyth 				if(debug['P'])
486*b370703fSCharles.Forsyth 					print("; %D set and !f; f=%d", v1, f);
487*b370703fSCharles.Forsyth 			}
488*b370703fSCharles.Forsyth 		}
489*b370703fSCharles.Forsyth 		if(debug['P'])
490*b370703fSCharles.Forsyth 			print("\n");
491*b370703fSCharles.Forsyth 		if(r->s2)
492*b370703fSCharles.Forsyth 			if(!copy1(v1, v2, r->s2, f))
493*b370703fSCharles.Forsyth 				return 0;
494*b370703fSCharles.Forsyth 	}
495*b370703fSCharles.Forsyth 	return 1;
496*b370703fSCharles.Forsyth }
497*b370703fSCharles.Forsyth 
498*b370703fSCharles.Forsyth /*
499*b370703fSCharles.Forsyth  * return
500*b370703fSCharles.Forsyth  * 1 if v only used (and substitute),
501*b370703fSCharles.Forsyth  * 2 if read-alter-rewrite
502*b370703fSCharles.Forsyth  * 3 if set
503*b370703fSCharles.Forsyth  * 4 if set and used
504*b370703fSCharles.Forsyth  * 0 otherwise (not touched)
505*b370703fSCharles.Forsyth  */
506*b370703fSCharles.Forsyth int
copyu(Prog * p,Adr * v,Adr * s)507*b370703fSCharles.Forsyth copyu(Prog *p, Adr *v, Adr *s)
508*b370703fSCharles.Forsyth {
509*b370703fSCharles.Forsyth 
510*b370703fSCharles.Forsyth 	switch(p->as) {
511*b370703fSCharles.Forsyth 
512*b370703fSCharles.Forsyth 	default:
513*b370703fSCharles.Forsyth 		if(debug['P'])
514*b370703fSCharles.Forsyth 			print("unknown op %A\n", p->as);
515*b370703fSCharles.Forsyth 		/* SBBL; ADCL; FLD1; SAHF */
516*b370703fSCharles.Forsyth 		return 2;
517*b370703fSCharles.Forsyth 
518*b370703fSCharles.Forsyth 
519*b370703fSCharles.Forsyth 	case ANEGB:
520*b370703fSCharles.Forsyth 	case ANEGW:
521*b370703fSCharles.Forsyth 	case ANEGL:
522*b370703fSCharles.Forsyth 	case ANEGQ:
523*b370703fSCharles.Forsyth 	case ANOTB:
524*b370703fSCharles.Forsyth 	case ANOTW:
525*b370703fSCharles.Forsyth 	case ANOTL:
526*b370703fSCharles.Forsyth 	case ANOTQ:
527*b370703fSCharles.Forsyth 		if(copyas(&p->to, v))
528*b370703fSCharles.Forsyth 			return 2;
529*b370703fSCharles.Forsyth 		break;
530*b370703fSCharles.Forsyth 
531*b370703fSCharles.Forsyth 	case ALEAL:	/* lhs addr, rhs store */
532*b370703fSCharles.Forsyth 	case ALEAQ:
533*b370703fSCharles.Forsyth 		if(copyas(&p->from, v))
534*b370703fSCharles.Forsyth 			return 2;
535*b370703fSCharles.Forsyth 
536*b370703fSCharles.Forsyth 
537*b370703fSCharles.Forsyth 	case ANOP:	/* rhs store */
538*b370703fSCharles.Forsyth 	case AMOVL:
539*b370703fSCharles.Forsyth 	case AMOVQ:
540*b370703fSCharles.Forsyth 	case AMOVBLSX:
541*b370703fSCharles.Forsyth 	case AMOVBLZX:
542*b370703fSCharles.Forsyth 	case AMOVBQSX:
543*b370703fSCharles.Forsyth 	case AMOVBQZX:
544*b370703fSCharles.Forsyth 	case AMOVLQSX:
545*b370703fSCharles.Forsyth 	case AMOVLQZX:
546*b370703fSCharles.Forsyth 	case AMOVWLSX:
547*b370703fSCharles.Forsyth 	case AMOVWLZX:
548*b370703fSCharles.Forsyth 	case AMOVWQSX:
549*b370703fSCharles.Forsyth 	case AMOVWQZX:
550*b370703fSCharles.Forsyth 
551*b370703fSCharles.Forsyth 	case AMOVSS:
552*b370703fSCharles.Forsyth 	case AMOVSD:
553*b370703fSCharles.Forsyth 	case ACVTSD2SL:
554*b370703fSCharles.Forsyth 	case ACVTSD2SQ:
555*b370703fSCharles.Forsyth 	case ACVTSD2SS:
556*b370703fSCharles.Forsyth 	case ACVTSL2SD:
557*b370703fSCharles.Forsyth 	case ACVTSL2SS:
558*b370703fSCharles.Forsyth 	case ACVTSQ2SD:
559*b370703fSCharles.Forsyth 	case ACVTSQ2SS:
560*b370703fSCharles.Forsyth 	case ACVTSS2SD:
561*b370703fSCharles.Forsyth 	case ACVTSS2SL:
562*b370703fSCharles.Forsyth 	case ACVTSS2SQ:
563*b370703fSCharles.Forsyth 	case ACVTTSD2SL:
564*b370703fSCharles.Forsyth 	case ACVTTSD2SQ:
565*b370703fSCharles.Forsyth 	case ACVTTSS2SL:
566*b370703fSCharles.Forsyth 	case ACVTTSS2SQ:
567*b370703fSCharles.Forsyth 		if(copyas(&p->to, v)) {
568*b370703fSCharles.Forsyth 			if(s != A)
569*b370703fSCharles.Forsyth 				return copysub(&p->from, v, s, 1);
570*b370703fSCharles.Forsyth 			if(copyau(&p->from, v))
571*b370703fSCharles.Forsyth 				return 4;
572*b370703fSCharles.Forsyth 			return 3;
573*b370703fSCharles.Forsyth 		}
574*b370703fSCharles.Forsyth 		goto caseread;
575*b370703fSCharles.Forsyth 
576*b370703fSCharles.Forsyth 	case AROLB:
577*b370703fSCharles.Forsyth 	case AROLL:
578*b370703fSCharles.Forsyth 	case AROLQ:
579*b370703fSCharles.Forsyth 	case AROLW:
580*b370703fSCharles.Forsyth 	case ARORB:
581*b370703fSCharles.Forsyth 	case ARORL:
582*b370703fSCharles.Forsyth 	case ARORQ:
583*b370703fSCharles.Forsyth 	case ARORW:
584*b370703fSCharles.Forsyth 	case ASALB:
585*b370703fSCharles.Forsyth 	case ASALL:
586*b370703fSCharles.Forsyth 	case ASALQ:
587*b370703fSCharles.Forsyth 	case ASALW:
588*b370703fSCharles.Forsyth 	case ASARB:
589*b370703fSCharles.Forsyth 	case ASARL:
590*b370703fSCharles.Forsyth 	case ASARQ:
591*b370703fSCharles.Forsyth 	case ASARW:
592*b370703fSCharles.Forsyth 	case ASHLB:
593*b370703fSCharles.Forsyth 	case ASHLL:
594*b370703fSCharles.Forsyth 	case ASHLQ:
595*b370703fSCharles.Forsyth 	case ASHLW:
596*b370703fSCharles.Forsyth 	case ASHRB:
597*b370703fSCharles.Forsyth 	case ASHRL:
598*b370703fSCharles.Forsyth 	case ASHRQ:
599*b370703fSCharles.Forsyth 	case ASHRW:
600*b370703fSCharles.Forsyth 		if(copyas(&p->to, v))
601*b370703fSCharles.Forsyth 			return 2;
602*b370703fSCharles.Forsyth 		if(copyas(&p->from, v))
603*b370703fSCharles.Forsyth 			if(p->from.type == D_CX)
604*b370703fSCharles.Forsyth 				return 2;
605*b370703fSCharles.Forsyth 		goto caseread;
606*b370703fSCharles.Forsyth 
607*b370703fSCharles.Forsyth 	case AADDB:	/* rhs rar */
608*b370703fSCharles.Forsyth 	case AADDL:
609*b370703fSCharles.Forsyth 	case AADDQ:
610*b370703fSCharles.Forsyth 	case AADDW:
611*b370703fSCharles.Forsyth 	case AANDB:
612*b370703fSCharles.Forsyth 	case AANDL:
613*b370703fSCharles.Forsyth 	case AANDQ:
614*b370703fSCharles.Forsyth 	case AANDW:
615*b370703fSCharles.Forsyth 	case ADECL:
616*b370703fSCharles.Forsyth 	case ADECQ:
617*b370703fSCharles.Forsyth 	case ADECW:
618*b370703fSCharles.Forsyth 	case AINCL:
619*b370703fSCharles.Forsyth 	case AINCQ:
620*b370703fSCharles.Forsyth 	case AINCW:
621*b370703fSCharles.Forsyth 	case ASUBB:
622*b370703fSCharles.Forsyth 	case ASUBL:
623*b370703fSCharles.Forsyth 	case ASUBQ:
624*b370703fSCharles.Forsyth 	case ASUBW:
625*b370703fSCharles.Forsyth 	case AORB:
626*b370703fSCharles.Forsyth 	case AORL:
627*b370703fSCharles.Forsyth 	case AORQ:
628*b370703fSCharles.Forsyth 	case AORW:
629*b370703fSCharles.Forsyth 	case AXORB:
630*b370703fSCharles.Forsyth 	case AXORL:
631*b370703fSCharles.Forsyth 	case AXORQ:
632*b370703fSCharles.Forsyth 	case AXORW:
633*b370703fSCharles.Forsyth 	case AMOVB:
634*b370703fSCharles.Forsyth 	case AMOVW:
635*b370703fSCharles.Forsyth 
636*b370703fSCharles.Forsyth 	case AADDSD:
637*b370703fSCharles.Forsyth 	case AADDSS:
638*b370703fSCharles.Forsyth 	case ACMPSD:
639*b370703fSCharles.Forsyth 	case ACMPSS:
640*b370703fSCharles.Forsyth 	case ADIVSD:
641*b370703fSCharles.Forsyth 	case ADIVSS:
642*b370703fSCharles.Forsyth 	case AMAXSD:
643*b370703fSCharles.Forsyth 	case AMAXSS:
644*b370703fSCharles.Forsyth 	case AMINSD:
645*b370703fSCharles.Forsyth 	case AMINSS:
646*b370703fSCharles.Forsyth 	case AMULSD:
647*b370703fSCharles.Forsyth 	case AMULSS:
648*b370703fSCharles.Forsyth 	case ARCPSS:
649*b370703fSCharles.Forsyth 	case ARSQRTSS:
650*b370703fSCharles.Forsyth 	case ASQRTSD:
651*b370703fSCharles.Forsyth 	case ASQRTSS:
652*b370703fSCharles.Forsyth 	case ASUBSD:
653*b370703fSCharles.Forsyth 	case ASUBSS:
654*b370703fSCharles.Forsyth 	case AXORPD:
655*b370703fSCharles.Forsyth 		if(copyas(&p->to, v))
656*b370703fSCharles.Forsyth 			return 2;
657*b370703fSCharles.Forsyth 		goto caseread;
658*b370703fSCharles.Forsyth 
659*b370703fSCharles.Forsyth 	case ACMPL:	/* read only */
660*b370703fSCharles.Forsyth 	case ACMPW:
661*b370703fSCharles.Forsyth 	case ACMPB:
662*b370703fSCharles.Forsyth 	case ACMPQ:
663*b370703fSCharles.Forsyth 
664*b370703fSCharles.Forsyth 	case ACOMISD:
665*b370703fSCharles.Forsyth 	case ACOMISS:
666*b370703fSCharles.Forsyth 	case AUCOMISD:
667*b370703fSCharles.Forsyth 	case AUCOMISS:
668*b370703fSCharles.Forsyth 	caseread:
669*b370703fSCharles.Forsyth 		if(s != A) {
670*b370703fSCharles.Forsyth 			if(copysub(&p->from, v, s, 1))
671*b370703fSCharles.Forsyth 				return 1;
672*b370703fSCharles.Forsyth 			return copysub(&p->to, v, s, 1);
673*b370703fSCharles.Forsyth 		}
674*b370703fSCharles.Forsyth 		if(copyau(&p->from, v))
675*b370703fSCharles.Forsyth 			return 1;
676*b370703fSCharles.Forsyth 		if(copyau(&p->to, v))
677*b370703fSCharles.Forsyth 			return 1;
678*b370703fSCharles.Forsyth 		break;
679*b370703fSCharles.Forsyth 
680*b370703fSCharles.Forsyth 	case AJGE:	/* no reference */
681*b370703fSCharles.Forsyth 	case AJNE:
682*b370703fSCharles.Forsyth 	case AJLE:
683*b370703fSCharles.Forsyth 	case AJEQ:
684*b370703fSCharles.Forsyth 	case AJHI:
685*b370703fSCharles.Forsyth 	case AJLS:
686*b370703fSCharles.Forsyth 	case AJMI:
687*b370703fSCharles.Forsyth 	case AJPL:
688*b370703fSCharles.Forsyth 	case AJGT:
689*b370703fSCharles.Forsyth 	case AJLT:
690*b370703fSCharles.Forsyth 	case AJCC:
691*b370703fSCharles.Forsyth 	case AJCS:
692*b370703fSCharles.Forsyth 
693*b370703fSCharles.Forsyth 	case AADJSP:
694*b370703fSCharles.Forsyth 	case AWAIT:
695*b370703fSCharles.Forsyth 	case ACLD:
696*b370703fSCharles.Forsyth 		break;
697*b370703fSCharles.Forsyth 
698*b370703fSCharles.Forsyth 	case AIMULL:
699*b370703fSCharles.Forsyth 	case AIMULQ:
700*b370703fSCharles.Forsyth 	case AIMULW:
701*b370703fSCharles.Forsyth 		if(p->to.type != D_NONE) {
702*b370703fSCharles.Forsyth 			if(copyas(&p->to, v))
703*b370703fSCharles.Forsyth 				return 2;
704*b370703fSCharles.Forsyth 			goto caseread;
705*b370703fSCharles.Forsyth 		}
706*b370703fSCharles.Forsyth 
707*b370703fSCharles.Forsyth 	case ADIVB:
708*b370703fSCharles.Forsyth 	case ADIVL:
709*b370703fSCharles.Forsyth 	case ADIVQ:
710*b370703fSCharles.Forsyth 	case ADIVW:
711*b370703fSCharles.Forsyth 	case AIDIVB:
712*b370703fSCharles.Forsyth 	case AIDIVL:
713*b370703fSCharles.Forsyth 	case AIDIVQ:
714*b370703fSCharles.Forsyth 	case AIDIVW:
715*b370703fSCharles.Forsyth 	case AIMULB:
716*b370703fSCharles.Forsyth 	case AMULB:
717*b370703fSCharles.Forsyth 	case AMULL:
718*b370703fSCharles.Forsyth 	case AMULQ:
719*b370703fSCharles.Forsyth 	case AMULW:
720*b370703fSCharles.Forsyth 
721*b370703fSCharles.Forsyth 	case ACWD:
722*b370703fSCharles.Forsyth 	case ACDQ:
723*b370703fSCharles.Forsyth 	case ACQO:
724*b370703fSCharles.Forsyth 		if(v->type == D_AX || v->type == D_DX)
725*b370703fSCharles.Forsyth 			return 2;
726*b370703fSCharles.Forsyth 		goto caseread;
727*b370703fSCharles.Forsyth 
728*b370703fSCharles.Forsyth 	case AMOVSL:
729*b370703fSCharles.Forsyth 	case AMOVSQ:
730*b370703fSCharles.Forsyth 	case AREP:
731*b370703fSCharles.Forsyth 	case AREPN:
732*b370703fSCharles.Forsyth 		if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
733*b370703fSCharles.Forsyth 			return 2;
734*b370703fSCharles.Forsyth 		goto caseread;
735*b370703fSCharles.Forsyth 
736*b370703fSCharles.Forsyth 	case AJMP:	/* funny */
737*b370703fSCharles.Forsyth 		if(s != A) {
738*b370703fSCharles.Forsyth 			if(copysub(&p->to, v, s, 1))
739*b370703fSCharles.Forsyth 				return 1;
740*b370703fSCharles.Forsyth 			return 0;
741*b370703fSCharles.Forsyth 		}
742*b370703fSCharles.Forsyth 		if(copyau(&p->to, v))
743*b370703fSCharles.Forsyth 			return 1;
744*b370703fSCharles.Forsyth 		return 0;
745*b370703fSCharles.Forsyth 
746*b370703fSCharles.Forsyth 	case ARET:	/* funny */
747*b370703fSCharles.Forsyth 		if(v->type == REGRET || v->type == FREGRET)
748*b370703fSCharles.Forsyth 			return 2;
749*b370703fSCharles.Forsyth 		if(s != A)
750*b370703fSCharles.Forsyth 			return 1;
751*b370703fSCharles.Forsyth 		return 3;
752*b370703fSCharles.Forsyth 
753*b370703fSCharles.Forsyth 	case ACALL:	/* funny */
754*b370703fSCharles.Forsyth 		if(REGEXT && v->type <= REGEXT && v->type > exregoffset)
755*b370703fSCharles.Forsyth 			return 2;
756*b370703fSCharles.Forsyth 		if(REGARG && v->type == REGARG)
757*b370703fSCharles.Forsyth 			return 2;
758*b370703fSCharles.Forsyth 
759*b370703fSCharles.Forsyth 		if(s != A) {
760*b370703fSCharles.Forsyth 			if(copysub(&p->to, v, s, 1))
761*b370703fSCharles.Forsyth 				return 1;
762*b370703fSCharles.Forsyth 			return 0;
763*b370703fSCharles.Forsyth 		}
764*b370703fSCharles.Forsyth 		if(copyau(&p->to, v))
765*b370703fSCharles.Forsyth 			return 4;
766*b370703fSCharles.Forsyth 		return 3;
767*b370703fSCharles.Forsyth 
768*b370703fSCharles.Forsyth 	case ATEXT:	/* funny */
769*b370703fSCharles.Forsyth 		if(REGARG && v->type == REGARG)
770*b370703fSCharles.Forsyth 			return 3;
771*b370703fSCharles.Forsyth 		return 0;
772*b370703fSCharles.Forsyth 	}
773*b370703fSCharles.Forsyth 	return 0;
774*b370703fSCharles.Forsyth }
775*b370703fSCharles.Forsyth 
776*b370703fSCharles.Forsyth /*
777*b370703fSCharles.Forsyth  * direct reference,
778*b370703fSCharles.Forsyth  * could be set/use depending on
779*b370703fSCharles.Forsyth  * semantics
780*b370703fSCharles.Forsyth  */
781*b370703fSCharles.Forsyth int
copyas(Adr * a,Adr * v)782*b370703fSCharles.Forsyth copyas(Adr *a, Adr *v)
783*b370703fSCharles.Forsyth {
784*b370703fSCharles.Forsyth 	if(a->type != v->type)
785*b370703fSCharles.Forsyth 		return 0;
786*b370703fSCharles.Forsyth 	if(regtyp(v))
787*b370703fSCharles.Forsyth 		return 1;
788*b370703fSCharles.Forsyth 	if(v->type == D_AUTO || v->type == D_PARAM)
789*b370703fSCharles.Forsyth 		if(v->offset == a->offset)
790*b370703fSCharles.Forsyth 			return 1;
791*b370703fSCharles.Forsyth 	return 0;
792*b370703fSCharles.Forsyth }
793*b370703fSCharles.Forsyth 
794*b370703fSCharles.Forsyth /*
795*b370703fSCharles.Forsyth  * either direct or indirect
796*b370703fSCharles.Forsyth  */
797*b370703fSCharles.Forsyth int
copyau(Adr * a,Adr * v)798*b370703fSCharles.Forsyth copyau(Adr *a, Adr *v)
799*b370703fSCharles.Forsyth {
800*b370703fSCharles.Forsyth 
801*b370703fSCharles.Forsyth 	if(copyas(a, v))
802*b370703fSCharles.Forsyth 		return 1;
803*b370703fSCharles.Forsyth 	if(regtyp(v)) {
804*b370703fSCharles.Forsyth 		if(a->type-D_INDIR == v->type)
805*b370703fSCharles.Forsyth 			return 1;
806*b370703fSCharles.Forsyth 		if(a->index == v->type)
807*b370703fSCharles.Forsyth 			return 1;
808*b370703fSCharles.Forsyth 	}
809*b370703fSCharles.Forsyth 	return 0;
810*b370703fSCharles.Forsyth }
811*b370703fSCharles.Forsyth 
812*b370703fSCharles.Forsyth /*
813*b370703fSCharles.Forsyth  * substitute s for v in a
814*b370703fSCharles.Forsyth  * return failure to substitute
815*b370703fSCharles.Forsyth  */
816*b370703fSCharles.Forsyth int
copysub(Adr * a,Adr * v,Adr * s,int f)817*b370703fSCharles.Forsyth copysub(Adr *a, Adr *v, Adr *s, int f)
818*b370703fSCharles.Forsyth {
819*b370703fSCharles.Forsyth 	int t;
820*b370703fSCharles.Forsyth 
821*b370703fSCharles.Forsyth 	if(copyas(a, v)) {
822*b370703fSCharles.Forsyth 		t = s->type;
823*b370703fSCharles.Forsyth 		if(t >= D_AX && t <= D_R15 || t >= D_X0 && t <= D_X0+15) {
824*b370703fSCharles.Forsyth 			if(f)
825*b370703fSCharles.Forsyth 				a->type = t;
826*b370703fSCharles.Forsyth 		}
827*b370703fSCharles.Forsyth 		return 0;
828*b370703fSCharles.Forsyth 	}
829*b370703fSCharles.Forsyth 	if(regtyp(v)) {
830*b370703fSCharles.Forsyth 		t = v->type;
831*b370703fSCharles.Forsyth 		if(a->type == t+D_INDIR) {
832*b370703fSCharles.Forsyth 			if((s->type == D_BP || s->type == D_R13) && a->index != D_NONE)
833*b370703fSCharles.Forsyth 				return 1;	/* can't use BP-base with index */
834*b370703fSCharles.Forsyth 			if(f)
835*b370703fSCharles.Forsyth 				a->type = s->type+D_INDIR;
836*b370703fSCharles.Forsyth //			return 0;
837*b370703fSCharles.Forsyth 		}
838*b370703fSCharles.Forsyth 		if(a->index == t) {
839*b370703fSCharles.Forsyth 			if(f)
840*b370703fSCharles.Forsyth 				a->index = s->type;
841*b370703fSCharles.Forsyth 			return 0;
842*b370703fSCharles.Forsyth 		}
843*b370703fSCharles.Forsyth 		return 0;
844*b370703fSCharles.Forsyth 	}
845*b370703fSCharles.Forsyth 	return 0;
846*b370703fSCharles.Forsyth }
847