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