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