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