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