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