1e887ea33SDavid du Colombier #include "gc.h"
2e887ea33SDavid du Colombier
3e887ea33SDavid du Colombier Reg*
rega(void)4e887ea33SDavid du Colombier rega(void)
5e887ea33SDavid du Colombier {
6e887ea33SDavid du Colombier Reg *r;
7e887ea33SDavid du Colombier
8e887ea33SDavid du Colombier r = freer;
9e887ea33SDavid du Colombier if(r == R) {
10e887ea33SDavid du Colombier r = alloc(sizeof(*r));
11e887ea33SDavid du Colombier } else
12e887ea33SDavid du Colombier freer = r->link;
13e887ea33SDavid du Colombier
14e887ea33SDavid du Colombier *r = zreg;
15e887ea33SDavid du Colombier return r;
16e887ea33SDavid du Colombier }
17e887ea33SDavid du Colombier
18e887ea33SDavid du Colombier int
rcmp(const void * a1,const void * a2)19e887ea33SDavid du Colombier rcmp(const void *a1, const void *a2)
20e887ea33SDavid du Colombier {
21e887ea33SDavid du Colombier Rgn *p1, *p2;
22e887ea33SDavid du Colombier int c1, c2;
23e887ea33SDavid du Colombier
24e887ea33SDavid du Colombier p1 = (Rgn*)a1;
25e887ea33SDavid du Colombier p2 = (Rgn*)a2;
26e887ea33SDavid du Colombier c1 = p2->cost;
27e887ea33SDavid du Colombier c2 = p1->cost;
28e887ea33SDavid du Colombier if(c1 -= c2)
29e887ea33SDavid du Colombier return c1;
30e887ea33SDavid du Colombier return p2->varno - p1->varno;
31e887ea33SDavid du Colombier }
32e887ea33SDavid du Colombier
33e887ea33SDavid du Colombier void
regopt(Prog * p)34e887ea33SDavid du Colombier regopt(Prog *p)
35e887ea33SDavid du Colombier {
36e887ea33SDavid du Colombier Reg *r, *r1, *r2;
37e887ea33SDavid du Colombier Prog *p1;
38e887ea33SDavid du Colombier int i, z;
39e887ea33SDavid du Colombier long initpc, val, npc;
40e887ea33SDavid du Colombier ulong vreg;
41e887ea33SDavid du Colombier Bits bit;
42e887ea33SDavid du Colombier struct
43e887ea33SDavid du Colombier {
44e887ea33SDavid du Colombier long m;
45e887ea33SDavid du Colombier long c;
46e887ea33SDavid du Colombier Reg* p;
47e887ea33SDavid du Colombier } log5[6], *lp;
48e887ea33SDavid du Colombier
49e887ea33SDavid du Colombier firstr = R;
50e887ea33SDavid du Colombier lastr = R;
51e887ea33SDavid du Colombier nvar = 0;
52e887ea33SDavid du Colombier regbits = RtoB(D_SP) | RtoB(D_AX) | RtoB(D_X0);
53*b94bb474SDavid du Colombier if(REGEXT)
54*b94bb474SDavid du Colombier regbits |= RtoB(REGEXT) | RtoB(REGEXT-1);
55e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
56e887ea33SDavid du Colombier externs.b[z] = 0;
57e887ea33SDavid du Colombier params.b[z] = 0;
58e887ea33SDavid du Colombier consts.b[z] = 0;
59e887ea33SDavid du Colombier addrs.b[z] = 0;
60e887ea33SDavid du Colombier }
61e887ea33SDavid du Colombier
62e887ea33SDavid du Colombier /*
63e887ea33SDavid du Colombier * pass 1
64e887ea33SDavid du Colombier * build aux data structure
65e887ea33SDavid du Colombier * allocate pcs
66e887ea33SDavid du Colombier * find use and set of variables
67e887ea33SDavid du Colombier */
68e887ea33SDavid du Colombier val = 5L * 5L * 5L * 5L * 5L;
69e887ea33SDavid du Colombier lp = log5;
70e887ea33SDavid du Colombier for(i=0; i<5; i++) {
71e887ea33SDavid du Colombier lp->m = val;
72e887ea33SDavid du Colombier lp->c = 0;
73e887ea33SDavid du Colombier lp->p = R;
74e887ea33SDavid du Colombier val /= 5L;
75e887ea33SDavid du Colombier lp++;
76e887ea33SDavid du Colombier }
77e887ea33SDavid du Colombier val = 0;
78e887ea33SDavid du Colombier for(; p != P; p = p->link) {
79e887ea33SDavid du Colombier switch(p->as) {
80e887ea33SDavid du Colombier case ADATA:
81e887ea33SDavid du Colombier case AGLOBL:
82e887ea33SDavid du Colombier case ANAME:
83e887ea33SDavid du Colombier case ASIGNAME:
84e887ea33SDavid du Colombier continue;
85e887ea33SDavid du Colombier }
86e887ea33SDavid du Colombier r = rega();
87e887ea33SDavid du Colombier if(firstr == R) {
88e887ea33SDavid du Colombier firstr = r;
89e887ea33SDavid du Colombier lastr = r;
90e887ea33SDavid du Colombier } else {
91e887ea33SDavid du Colombier lastr->link = r;
92e887ea33SDavid du Colombier r->p1 = lastr;
93e887ea33SDavid du Colombier lastr->s1 = r;
94e887ea33SDavid du Colombier lastr = r;
95e887ea33SDavid du Colombier }
96e887ea33SDavid du Colombier r->prog = p;
97e887ea33SDavid du Colombier r->pc = val;
98e887ea33SDavid du Colombier val++;
99e887ea33SDavid du Colombier
100e887ea33SDavid du Colombier lp = log5;
101e887ea33SDavid du Colombier for(i=0; i<5; i++) {
102e887ea33SDavid du Colombier lp->c--;
103e887ea33SDavid du Colombier if(lp->c <= 0) {
104e887ea33SDavid du Colombier lp->c = lp->m;
105e887ea33SDavid du Colombier if(lp->p != R)
106e887ea33SDavid du Colombier lp->p->log5 = r;
107e887ea33SDavid du Colombier lp->p = r;
108e887ea33SDavid du Colombier (lp+1)->c = 0;
109e887ea33SDavid du Colombier break;
110e887ea33SDavid du Colombier }
111e887ea33SDavid du Colombier lp++;
112e887ea33SDavid du Colombier }
113e887ea33SDavid du Colombier
114e887ea33SDavid du Colombier r1 = r->p1;
115e887ea33SDavid du Colombier if(r1 != R)
116e887ea33SDavid du Colombier switch(r1->prog->as) {
117e887ea33SDavid du Colombier case ARET:
118e887ea33SDavid du Colombier case AJMP:
119e887ea33SDavid du Colombier case AIRETL:
120e887ea33SDavid du Colombier case AIRETQ:
121e887ea33SDavid du Colombier r->p1 = R;
122e887ea33SDavid du Colombier r1->s1 = R;
123e887ea33SDavid du Colombier }
124e887ea33SDavid du Colombier
125e887ea33SDavid du Colombier bit = mkvar(r, &p->from);
126e887ea33SDavid du Colombier if(bany(&bit))
127e887ea33SDavid du Colombier switch(p->as) {
128e887ea33SDavid du Colombier /*
129e887ea33SDavid du Colombier * funny
130e887ea33SDavid du Colombier */
131e887ea33SDavid du Colombier case ALEAL:
132e887ea33SDavid du Colombier case ALEAQ:
133e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
134e887ea33SDavid du Colombier addrs.b[z] |= bit.b[z];
135e887ea33SDavid du Colombier break;
136e887ea33SDavid du Colombier
137e887ea33SDavid du Colombier /*
138e887ea33SDavid du Colombier * left side read
139e887ea33SDavid du Colombier */
140e887ea33SDavid du Colombier default:
141e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
142e887ea33SDavid du Colombier r->use1.b[z] |= bit.b[z];
143e887ea33SDavid du Colombier break;
144e887ea33SDavid du Colombier }
145e887ea33SDavid du Colombier
146e887ea33SDavid du Colombier bit = mkvar(r, &p->to);
147e887ea33SDavid du Colombier if(bany(&bit))
148e887ea33SDavid du Colombier switch(p->as) {
149e887ea33SDavid du Colombier default:
150e887ea33SDavid du Colombier diag(Z, "reg: unknown op: %A", p->as);
151e887ea33SDavid du Colombier break;
152e887ea33SDavid du Colombier
153e887ea33SDavid du Colombier /*
154e887ea33SDavid du Colombier * right side read
155e887ea33SDavid du Colombier */
156e887ea33SDavid du Colombier case ACMPB:
157e887ea33SDavid du Colombier case ACMPL:
158e887ea33SDavid du Colombier case ACMPQ:
159e887ea33SDavid du Colombier case ACMPW:
160e887ea33SDavid du Colombier case ACOMISS:
161e887ea33SDavid du Colombier case ACOMISD:
162e887ea33SDavid du Colombier case AUCOMISS:
163e887ea33SDavid du Colombier case AUCOMISD:
164e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
165e887ea33SDavid du Colombier r->use2.b[z] |= bit.b[z];
166e887ea33SDavid du Colombier break;
167e887ea33SDavid du Colombier
168e887ea33SDavid du Colombier /*
169e887ea33SDavid du Colombier * right side write
170e887ea33SDavid du Colombier */
171e887ea33SDavid du Colombier case ANOP:
172e887ea33SDavid du Colombier case AMOVL:
173e887ea33SDavid du Colombier case AMOVQ:
174e887ea33SDavid du Colombier case AMOVB:
175e887ea33SDavid du Colombier case AMOVW:
176e887ea33SDavid du Colombier case AMOVBLSX:
177e887ea33SDavid du Colombier case AMOVBLZX:
178e887ea33SDavid du Colombier case AMOVBQSX:
179e887ea33SDavid du Colombier case AMOVBQZX:
180e887ea33SDavid du Colombier case AMOVLQSX:
181e887ea33SDavid du Colombier case AMOVLQZX:
182e887ea33SDavid du Colombier case AMOVWLSX:
183e887ea33SDavid du Colombier case AMOVWLZX:
184e887ea33SDavid du Colombier case AMOVWQSX:
185e887ea33SDavid du Colombier case AMOVWQZX:
186e887ea33SDavid du Colombier
187e887ea33SDavid du Colombier case AMOVSS:
188e887ea33SDavid du Colombier case AMOVSD:
189e887ea33SDavid du Colombier case ACVTSD2SL:
190e887ea33SDavid du Colombier case ACVTSD2SQ:
191e887ea33SDavid du Colombier case ACVTSD2SS:
192e887ea33SDavid du Colombier case ACVTSL2SD:
193e887ea33SDavid du Colombier case ACVTSL2SS:
194e887ea33SDavid du Colombier case ACVTSQ2SD:
195e887ea33SDavid du Colombier case ACVTSQ2SS:
196e887ea33SDavid du Colombier case ACVTSS2SD:
197e887ea33SDavid du Colombier case ACVTSS2SL:
198e887ea33SDavid du Colombier case ACVTSS2SQ:
199e887ea33SDavid du Colombier case ACVTTSD2SL:
200e887ea33SDavid du Colombier case ACVTTSD2SQ:
201e887ea33SDavid du Colombier case ACVTTSS2SL:
202e887ea33SDavid du Colombier case ACVTTSS2SQ:
203e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
204e887ea33SDavid du Colombier r->set.b[z] |= bit.b[z];
205e887ea33SDavid du Colombier break;
206e887ea33SDavid du Colombier
207e887ea33SDavid du Colombier /*
208e887ea33SDavid du Colombier * right side read+write
209e887ea33SDavid du Colombier */
210e887ea33SDavid du Colombier case AADDB:
211e887ea33SDavid du Colombier case AADDL:
212e887ea33SDavid du Colombier case AADDQ:
213e887ea33SDavid du Colombier case AADDW:
214e887ea33SDavid du Colombier case AANDB:
215e887ea33SDavid du Colombier case AANDL:
216e887ea33SDavid du Colombier case AANDQ:
217e887ea33SDavid du Colombier case AANDW:
218e887ea33SDavid du Colombier case ASUBB:
219e887ea33SDavid du Colombier case ASUBL:
220e887ea33SDavid du Colombier case ASUBQ:
221e887ea33SDavid du Colombier case ASUBW:
222e887ea33SDavid du Colombier case AORB:
223e887ea33SDavid du Colombier case AORL:
224e887ea33SDavid du Colombier case AORQ:
225e887ea33SDavid du Colombier case AORW:
226e887ea33SDavid du Colombier case AXORB:
227e887ea33SDavid du Colombier case AXORL:
228e887ea33SDavid du Colombier case AXORQ:
229e887ea33SDavid du Colombier case AXORW:
230e887ea33SDavid du Colombier case ASALB:
231e887ea33SDavid du Colombier case ASALL:
232e887ea33SDavid du Colombier case ASALQ:
233e887ea33SDavid du Colombier case ASALW:
234e887ea33SDavid du Colombier case ASARB:
235e887ea33SDavid du Colombier case ASARL:
236e887ea33SDavid du Colombier case ASARQ:
237e887ea33SDavid du Colombier case ASARW:
238e887ea33SDavid du Colombier case AROLB:
239e887ea33SDavid du Colombier case AROLL:
240e887ea33SDavid du Colombier case AROLQ:
241e887ea33SDavid du Colombier case AROLW:
242e887ea33SDavid du Colombier case ARORB:
243e887ea33SDavid du Colombier case ARORL:
244e887ea33SDavid du Colombier case ARORQ:
245e887ea33SDavid du Colombier case ARORW:
246e887ea33SDavid du Colombier case ASHLB:
247e887ea33SDavid du Colombier case ASHLL:
248e887ea33SDavid du Colombier case ASHLQ:
249e887ea33SDavid du Colombier case ASHLW:
250e887ea33SDavid du Colombier case ASHRB:
251e887ea33SDavid du Colombier case ASHRL:
252e887ea33SDavid du Colombier case ASHRQ:
253e887ea33SDavid du Colombier case ASHRW:
254e887ea33SDavid du Colombier case AIMULL:
255e887ea33SDavid du Colombier case AIMULQ:
256e887ea33SDavid du Colombier case AIMULW:
257e887ea33SDavid du Colombier case ANEGL:
258e887ea33SDavid du Colombier case ANEGQ:
259e887ea33SDavid du Colombier case ANOTL:
260e887ea33SDavid du Colombier case ANOTQ:
261e887ea33SDavid du Colombier case AADCL:
262e887ea33SDavid du Colombier case AADCQ:
263e887ea33SDavid du Colombier case ASBBL:
264e887ea33SDavid du Colombier case ASBBQ:
265e887ea33SDavid du Colombier
266e887ea33SDavid du Colombier case AADDSD:
267e887ea33SDavid du Colombier case AADDSS:
268e887ea33SDavid du Colombier case ACMPSD:
269e887ea33SDavid du Colombier case ACMPSS:
270e887ea33SDavid du Colombier case ADIVSD:
271e887ea33SDavid du Colombier case ADIVSS:
272e887ea33SDavid du Colombier case AMAXSD:
273e887ea33SDavid du Colombier case AMAXSS:
274e887ea33SDavid du Colombier case AMINSD:
275e887ea33SDavid du Colombier case AMINSS:
276e887ea33SDavid du Colombier case AMULSD:
277e887ea33SDavid du Colombier case AMULSS:
278e887ea33SDavid du Colombier case ARCPSS:
279e887ea33SDavid du Colombier case ARSQRTSS:
280e887ea33SDavid du Colombier case ASQRTSD:
281e887ea33SDavid du Colombier case ASQRTSS:
282e887ea33SDavid du Colombier case ASUBSD:
283e887ea33SDavid du Colombier case ASUBSS:
284e887ea33SDavid du Colombier case AXORPD:
285e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
286e887ea33SDavid du Colombier r->set.b[z] |= bit.b[z];
287e887ea33SDavid du Colombier r->use2.b[z] |= bit.b[z];
288e887ea33SDavid du Colombier }
289e887ea33SDavid du Colombier break;
290e887ea33SDavid du Colombier
291e887ea33SDavid du Colombier /*
292e887ea33SDavid du Colombier * funny
293e887ea33SDavid du Colombier */
294e887ea33SDavid du Colombier case ACALL:
295e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
296e887ea33SDavid du Colombier addrs.b[z] |= bit.b[z];
297e887ea33SDavid du Colombier break;
298e887ea33SDavid du Colombier }
299e887ea33SDavid du Colombier
300e887ea33SDavid du Colombier switch(p->as) {
301e887ea33SDavid du Colombier case AIMULL:
302e887ea33SDavid du Colombier case AIMULQ:
303e887ea33SDavid du Colombier case AIMULW:
304e887ea33SDavid du Colombier if(p->to.type != D_NONE)
305e887ea33SDavid du Colombier break;
306e887ea33SDavid du Colombier
307e887ea33SDavid du Colombier case AIDIVB:
308e887ea33SDavid du Colombier case AIDIVL:
309e887ea33SDavid du Colombier case AIDIVQ:
310e887ea33SDavid du Colombier case AIDIVW:
311e887ea33SDavid du Colombier case AIMULB:
312e887ea33SDavid du Colombier case ADIVB:
313e887ea33SDavid du Colombier case ADIVL:
314e887ea33SDavid du Colombier case ADIVQ:
315e887ea33SDavid du Colombier case ADIVW:
316e887ea33SDavid du Colombier case AMULB:
317e887ea33SDavid du Colombier case AMULL:
318e887ea33SDavid du Colombier case AMULQ:
319e887ea33SDavid du Colombier case AMULW:
320e887ea33SDavid du Colombier
321e887ea33SDavid du Colombier case ACWD:
322e887ea33SDavid du Colombier case ACDQ:
323e887ea33SDavid du Colombier case ACQO:
324e887ea33SDavid du Colombier r->regu |= RtoB(D_AX) | RtoB(D_DX);
325e887ea33SDavid du Colombier break;
326e887ea33SDavid du Colombier
327e887ea33SDavid du Colombier case AREP:
328e887ea33SDavid du Colombier case AREPN:
329e887ea33SDavid du Colombier case ALOOP:
330e887ea33SDavid du Colombier case ALOOPEQ:
331e887ea33SDavid du Colombier case ALOOPNE:
332e887ea33SDavid du Colombier r->regu |= RtoB(D_CX);
333e887ea33SDavid du Colombier break;
334e887ea33SDavid du Colombier
335e887ea33SDavid du Colombier case AMOVSB:
336e887ea33SDavid du Colombier case AMOVSL:
337e887ea33SDavid du Colombier case AMOVSQ:
338e887ea33SDavid du Colombier case AMOVSW:
339e887ea33SDavid du Colombier case ACMPSB:
340e887ea33SDavid du Colombier case ACMPSL:
341e887ea33SDavid du Colombier case ACMPSQ:
342e887ea33SDavid du Colombier case ACMPSW:
343e887ea33SDavid du Colombier r->regu |= RtoB(D_SI) | RtoB(D_DI);
344e887ea33SDavid du Colombier break;
345e887ea33SDavid du Colombier
346e887ea33SDavid du Colombier case ASTOSB:
347e887ea33SDavid du Colombier case ASTOSL:
348e887ea33SDavid du Colombier case ASTOSQ:
349e887ea33SDavid du Colombier case ASTOSW:
350e887ea33SDavid du Colombier case ASCASB:
351e887ea33SDavid du Colombier case ASCASL:
352e887ea33SDavid du Colombier case ASCASQ:
353e887ea33SDavid du Colombier case ASCASW:
354e887ea33SDavid du Colombier r->regu |= RtoB(D_AX) | RtoB(D_DI);
355e887ea33SDavid du Colombier break;
356e887ea33SDavid du Colombier
357e887ea33SDavid du Colombier case AINSB:
358e887ea33SDavid du Colombier case AINSL:
359e887ea33SDavid du Colombier case AINSW:
360e887ea33SDavid du Colombier case AOUTSB:
361e887ea33SDavid du Colombier case AOUTSL:
362e887ea33SDavid du Colombier case AOUTSW:
363e887ea33SDavid du Colombier r->regu |= RtoB(D_DI) | RtoB(D_DX);
364e887ea33SDavid du Colombier break;
365e887ea33SDavid du Colombier }
366e887ea33SDavid du Colombier }
367e887ea33SDavid du Colombier if(firstr == R)
368e887ea33SDavid du Colombier return;
369e887ea33SDavid du Colombier initpc = pc - val;
370e887ea33SDavid du Colombier npc = val;
371e887ea33SDavid du Colombier
372e887ea33SDavid du Colombier /*
373e887ea33SDavid du Colombier * pass 2
374e887ea33SDavid du Colombier * turn branch references to pointers
375e887ea33SDavid du Colombier * build back pointers
376e887ea33SDavid du Colombier */
377e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link) {
378e887ea33SDavid du Colombier p = r->prog;
379e887ea33SDavid du Colombier if(p->to.type == D_BRANCH) {
380e887ea33SDavid du Colombier val = p->to.offset - initpc;
381e887ea33SDavid du Colombier r1 = firstr;
382e887ea33SDavid du Colombier while(r1 != R) {
383e887ea33SDavid du Colombier r2 = r1->log5;
384e887ea33SDavid du Colombier if(r2 != R && val >= r2->pc) {
385e887ea33SDavid du Colombier r1 = r2;
386e887ea33SDavid du Colombier continue;
387e887ea33SDavid du Colombier }
388e887ea33SDavid du Colombier if(r1->pc == val)
389e887ea33SDavid du Colombier break;
390e887ea33SDavid du Colombier r1 = r1->link;
391e887ea33SDavid du Colombier }
392e887ea33SDavid du Colombier if(r1 == R) {
393e887ea33SDavid du Colombier nearln = p->lineno;
394e887ea33SDavid du Colombier diag(Z, "ref not found\n%P", p);
395e887ea33SDavid du Colombier continue;
396e887ea33SDavid du Colombier }
397e887ea33SDavid du Colombier if(r1 == r) {
398e887ea33SDavid du Colombier nearln = p->lineno;
399e887ea33SDavid du Colombier diag(Z, "ref to self\n%P", p);
400e887ea33SDavid du Colombier continue;
401e887ea33SDavid du Colombier }
402e887ea33SDavid du Colombier r->s2 = r1;
403e887ea33SDavid du Colombier r->p2link = r1->p2;
404e887ea33SDavid du Colombier r1->p2 = r;
405e887ea33SDavid du Colombier }
406e887ea33SDavid du Colombier }
407e887ea33SDavid du Colombier if(debug['R']) {
408e887ea33SDavid du Colombier p = firstr->prog;
409e887ea33SDavid du Colombier print("\n%L %D\n", p->lineno, &p->from);
410e887ea33SDavid du Colombier }
411e887ea33SDavid du Colombier
412e887ea33SDavid du Colombier /*
413e887ea33SDavid du Colombier * pass 2.5
414e887ea33SDavid du Colombier * find looping structure
415e887ea33SDavid du Colombier */
416e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link)
417e887ea33SDavid du Colombier r->active = 0;
418e887ea33SDavid du Colombier change = 0;
419e887ea33SDavid du Colombier loopit(firstr, npc);
420e887ea33SDavid du Colombier if(debug['R'] && debug['v']) {
421e887ea33SDavid du Colombier print("\nlooping structure:\n");
422e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link) {
423e887ea33SDavid du Colombier print("%ld:%P", r->loop, r->prog);
424e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
425e887ea33SDavid du Colombier bit.b[z] = r->use1.b[z] |
426e887ea33SDavid du Colombier r->use2.b[z] |
427e887ea33SDavid du Colombier r->set.b[z];
428e887ea33SDavid du Colombier if(bany(&bit)) {
429e887ea33SDavid du Colombier print("\t");
430e887ea33SDavid du Colombier if(bany(&r->use1))
431e887ea33SDavid du Colombier print(" u1=%B", r->use1);
432e887ea33SDavid du Colombier if(bany(&r->use2))
433e887ea33SDavid du Colombier print(" u2=%B", r->use2);
434e887ea33SDavid du Colombier if(bany(&r->set))
435e887ea33SDavid du Colombier print(" st=%B", r->set);
436e887ea33SDavid du Colombier }
437e887ea33SDavid du Colombier print("\n");
438e887ea33SDavid du Colombier }
439e887ea33SDavid du Colombier }
440e887ea33SDavid du Colombier
441e887ea33SDavid du Colombier /*
442e887ea33SDavid du Colombier * pass 3
443e887ea33SDavid du Colombier * iterate propagating usage
444e887ea33SDavid du Colombier * back until flow graph is complete
445e887ea33SDavid du Colombier */
446e887ea33SDavid du Colombier loop1:
447e887ea33SDavid du Colombier change = 0;
448e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link)
449e887ea33SDavid du Colombier r->active = 0;
450e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link)
451e887ea33SDavid du Colombier if(r->prog->as == ARET)
452e887ea33SDavid du Colombier prop(r, zbits, zbits);
453e887ea33SDavid du Colombier loop11:
454e887ea33SDavid du Colombier /* pick up unreachable code */
455e887ea33SDavid du Colombier i = 0;
456e887ea33SDavid du Colombier for(r = firstr; r != R; r = r1) {
457e887ea33SDavid du Colombier r1 = r->link;
458e887ea33SDavid du Colombier if(r1 && r1->active && !r->active) {
459e887ea33SDavid du Colombier prop(r, zbits, zbits);
460e887ea33SDavid du Colombier i = 1;
461e887ea33SDavid du Colombier }
462e887ea33SDavid du Colombier }
463e887ea33SDavid du Colombier if(i)
464e887ea33SDavid du Colombier goto loop11;
465e887ea33SDavid du Colombier if(change)
466e887ea33SDavid du Colombier goto loop1;
467e887ea33SDavid du Colombier
468e887ea33SDavid du Colombier
469e887ea33SDavid du Colombier /*
470e887ea33SDavid du Colombier * pass 4
471e887ea33SDavid du Colombier * iterate propagating register/variable synchrony
472e887ea33SDavid du Colombier * forward until graph is complete
473e887ea33SDavid du Colombier */
474e887ea33SDavid du Colombier loop2:
475e887ea33SDavid du Colombier change = 0;
476e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link)
477e887ea33SDavid du Colombier r->active = 0;
478e887ea33SDavid du Colombier synch(firstr, zbits);
479e887ea33SDavid du Colombier if(change)
480e887ea33SDavid du Colombier goto loop2;
481e887ea33SDavid du Colombier
482e887ea33SDavid du Colombier
483e887ea33SDavid du Colombier /*
484e887ea33SDavid du Colombier * pass 5
485e887ea33SDavid du Colombier * isolate regions
486e887ea33SDavid du Colombier * calculate costs (paint1)
487e887ea33SDavid du Colombier */
488e887ea33SDavid du Colombier r = firstr;
489e887ea33SDavid du Colombier if(r) {
490e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
491e887ea33SDavid du Colombier bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
492e887ea33SDavid du Colombier ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
493e887ea33SDavid du Colombier if(bany(&bit)) {
494e887ea33SDavid du Colombier nearln = r->prog->lineno;
495e887ea33SDavid du Colombier warn(Z, "used and not set: %B", bit);
496e887ea33SDavid du Colombier if(debug['R'] && !debug['w'])
497e887ea33SDavid du Colombier print("used and not set: %B\n", bit);
498e887ea33SDavid du Colombier }
499e887ea33SDavid du Colombier }
500e887ea33SDavid du Colombier if(debug['R'] && debug['v'])
501e887ea33SDavid du Colombier print("\nprop structure:\n");
502e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link)
503e887ea33SDavid du Colombier r->act = zbits;
504e887ea33SDavid du Colombier rgp = region;
505e887ea33SDavid du Colombier nregion = 0;
506e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link) {
507e887ea33SDavid du Colombier if(debug['R'] && debug['v']) {
508e887ea33SDavid du Colombier print("%P\t", r->prog);
509e887ea33SDavid du Colombier if(bany(&r->set))
510e887ea33SDavid du Colombier print("s:%B ", r->set);
511e887ea33SDavid du Colombier if(bany(&r->refahead))
512e887ea33SDavid du Colombier print("ra:%B ", r->refahead);
513e887ea33SDavid du Colombier if(bany(&r->calahead))
514e887ea33SDavid du Colombier print("ca:%B ", r->calahead);
515e887ea33SDavid du Colombier print("\n");
516e887ea33SDavid du Colombier }
517e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
518e887ea33SDavid du Colombier bit.b[z] = r->set.b[z] &
519e887ea33SDavid du Colombier ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
520e887ea33SDavid du Colombier if(bany(&bit)) {
521e887ea33SDavid du Colombier nearln = r->prog->lineno;
522e887ea33SDavid du Colombier warn(Z, "set and not used: %B", bit);
523e887ea33SDavid du Colombier if(debug['R'])
524e887ea33SDavid du Colombier print("set and not used: %B\n", bit);
525e887ea33SDavid du Colombier excise(r);
526e887ea33SDavid du Colombier }
527e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
528e887ea33SDavid du Colombier bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
529e887ea33SDavid du Colombier while(bany(&bit)) {
530e887ea33SDavid du Colombier i = bnum(bit);
531e887ea33SDavid du Colombier rgp->enter = r;
532e887ea33SDavid du Colombier rgp->varno = i;
533e887ea33SDavid du Colombier change = 0;
534e887ea33SDavid du Colombier if(debug['R'] && debug['v'])
535e887ea33SDavid du Colombier print("\n");
536e887ea33SDavid du Colombier paint1(r, i);
537e887ea33SDavid du Colombier bit.b[i/32] &= ~(1L<<(i%32));
538e887ea33SDavid du Colombier if(change <= 0) {
539e887ea33SDavid du Colombier if(debug['R'])
540e887ea33SDavid du Colombier print("%L$%d: %B\n",
541e887ea33SDavid du Colombier r->prog->lineno, change, blsh(i));
542e887ea33SDavid du Colombier continue;
543e887ea33SDavid du Colombier }
544e887ea33SDavid du Colombier rgp->cost = change;
545e887ea33SDavid du Colombier nregion++;
546e887ea33SDavid du Colombier if(nregion >= NRGN) {
547e887ea33SDavid du Colombier warn(Z, "too many regions");
548e887ea33SDavid du Colombier goto brk;
549e887ea33SDavid du Colombier }
550e887ea33SDavid du Colombier rgp++;
551e887ea33SDavid du Colombier }
552e887ea33SDavid du Colombier }
553e887ea33SDavid du Colombier brk:
554e887ea33SDavid du Colombier qsort(region, nregion, sizeof(region[0]), rcmp);
555e887ea33SDavid du Colombier
556e887ea33SDavid du Colombier /*
557e887ea33SDavid du Colombier * pass 6
558e887ea33SDavid du Colombier * determine used registers (paint2)
559e887ea33SDavid du Colombier * replace code (paint3)
560e887ea33SDavid du Colombier */
561e887ea33SDavid du Colombier rgp = region;
562e887ea33SDavid du Colombier for(i=0; i<nregion; i++) {
563e887ea33SDavid du Colombier bit = blsh(rgp->varno);
564e887ea33SDavid du Colombier vreg = paint2(rgp->enter, rgp->varno);
565e887ea33SDavid du Colombier vreg = allreg(vreg, rgp);
566e887ea33SDavid du Colombier if(debug['R']) {
567e887ea33SDavid du Colombier print("%L$%d %R: %B\n",
568e887ea33SDavid du Colombier rgp->enter->prog->lineno,
569e887ea33SDavid du Colombier rgp->cost,
570e887ea33SDavid du Colombier rgp->regno,
571e887ea33SDavid du Colombier bit);
572e887ea33SDavid du Colombier }
573e887ea33SDavid du Colombier if(rgp->regno != 0)
574e887ea33SDavid du Colombier paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
575e887ea33SDavid du Colombier rgp++;
576e887ea33SDavid du Colombier }
577e887ea33SDavid du Colombier /*
578e887ea33SDavid du Colombier * pass 7
579e887ea33SDavid du Colombier * peep-hole on basic block
580e887ea33SDavid du Colombier */
581e887ea33SDavid du Colombier if(!debug['R'] || debug['P'])
582e887ea33SDavid du Colombier peep();
583e887ea33SDavid du Colombier
584e887ea33SDavid du Colombier /*
585e887ea33SDavid du Colombier * pass 8
586e887ea33SDavid du Colombier * recalculate pc
587e887ea33SDavid du Colombier */
588e887ea33SDavid du Colombier val = initpc;
589e887ea33SDavid du Colombier for(r = firstr; r != R; r = r1) {
590e887ea33SDavid du Colombier r->pc = val;
591e887ea33SDavid du Colombier p = r->prog;
592e887ea33SDavid du Colombier p1 = P;
593e887ea33SDavid du Colombier r1 = r->link;
594e887ea33SDavid du Colombier if(r1 != R)
595e887ea33SDavid du Colombier p1 = r1->prog;
596e887ea33SDavid du Colombier for(; p != p1; p = p->link) {
597e887ea33SDavid du Colombier switch(p->as) {
598e887ea33SDavid du Colombier default:
599e887ea33SDavid du Colombier val++;
600e887ea33SDavid du Colombier break;
601e887ea33SDavid du Colombier
602e887ea33SDavid du Colombier case ANOP:
603e887ea33SDavid du Colombier case ADATA:
604e887ea33SDavid du Colombier case AGLOBL:
605e887ea33SDavid du Colombier case ANAME:
606e887ea33SDavid du Colombier case ASIGNAME:
607e887ea33SDavid du Colombier break;
608e887ea33SDavid du Colombier }
609e887ea33SDavid du Colombier }
610e887ea33SDavid du Colombier }
611e887ea33SDavid du Colombier pc = val;
612e887ea33SDavid du Colombier
613e887ea33SDavid du Colombier /*
614e887ea33SDavid du Colombier * fix up branches
615e887ea33SDavid du Colombier */
616e887ea33SDavid du Colombier if(debug['R'])
617e887ea33SDavid du Colombier if(bany(&addrs))
618e887ea33SDavid du Colombier print("addrs: %B\n", addrs);
619e887ea33SDavid du Colombier
620e887ea33SDavid du Colombier r1 = 0; /* set */
621e887ea33SDavid du Colombier for(r = firstr; r != R; r = r->link) {
622e887ea33SDavid du Colombier p = r->prog;
623e887ea33SDavid du Colombier if(p->to.type == D_BRANCH)
624e887ea33SDavid du Colombier p->to.offset = r->s2->pc;
625e887ea33SDavid du Colombier r1 = r;
626e887ea33SDavid du Colombier }
627e887ea33SDavid du Colombier
628e887ea33SDavid du Colombier /*
629e887ea33SDavid du Colombier * last pass
630e887ea33SDavid du Colombier * eliminate nops
631e887ea33SDavid du Colombier * free aux structures
632e887ea33SDavid du Colombier */
633e887ea33SDavid du Colombier for(p = firstr->prog; p != P; p = p->link){
634e887ea33SDavid du Colombier while(p->link && p->link->as == ANOP)
635e887ea33SDavid du Colombier p->link = p->link->link;
636e887ea33SDavid du Colombier }
637e887ea33SDavid du Colombier if(r1 != R) {
638e887ea33SDavid du Colombier r1->link = freer;
639e887ea33SDavid du Colombier freer = firstr;
640e887ea33SDavid du Colombier }
641e887ea33SDavid du Colombier }
642e887ea33SDavid du Colombier
643e887ea33SDavid du Colombier /*
644e887ea33SDavid du Colombier * add mov b,rn
645e887ea33SDavid du Colombier * just after r
646e887ea33SDavid du Colombier */
647e887ea33SDavid du Colombier void
addmove(Reg * r,int bn,int rn,int f)648e887ea33SDavid du Colombier addmove(Reg *r, int bn, int rn, int f)
649e887ea33SDavid du Colombier {
650e887ea33SDavid du Colombier Prog *p, *p1;
651e887ea33SDavid du Colombier Adr *a;
652e887ea33SDavid du Colombier Var *v;
653e887ea33SDavid du Colombier
654e887ea33SDavid du Colombier p1 = alloc(sizeof(*p1));
655e887ea33SDavid du Colombier *p1 = zprog;
656e887ea33SDavid du Colombier p = r->prog;
657e887ea33SDavid du Colombier
658e887ea33SDavid du Colombier p1->link = p->link;
659e887ea33SDavid du Colombier p->link = p1;
660e887ea33SDavid du Colombier p1->lineno = p->lineno;
661e887ea33SDavid du Colombier
662e887ea33SDavid du Colombier v = var + bn;
663e887ea33SDavid du Colombier
664e887ea33SDavid du Colombier a = &p1->to;
665e887ea33SDavid du Colombier a->sym = v->sym;
666e887ea33SDavid du Colombier a->offset = v->offset;
667e887ea33SDavid du Colombier a->etype = v->etype;
668e887ea33SDavid du Colombier a->type = v->name;
669e887ea33SDavid du Colombier
670e887ea33SDavid du Colombier p1->as = AMOVL;
671e887ea33SDavid du Colombier if(v->etype == TCHAR || v->etype == TUCHAR)
672e887ea33SDavid du Colombier p1->as = AMOVB;
673e887ea33SDavid du Colombier if(v->etype == TSHORT || v->etype == TUSHORT)
674e887ea33SDavid du Colombier p1->as = AMOVW;
675e887ea33SDavid du Colombier if(v->etype == TVLONG || v->etype == TUVLONG || v->etype == TIND)
676e887ea33SDavid du Colombier p1->as = AMOVQ;
677e887ea33SDavid du Colombier if(v->etype == TFLOAT)
678e887ea33SDavid du Colombier p1->as = AMOVSS;
679e887ea33SDavid du Colombier if(v->etype == TDOUBLE)
680e887ea33SDavid du Colombier p1->as = AMOVSD;
681e887ea33SDavid du Colombier
682e887ea33SDavid du Colombier p1->from.type = rn;
683e887ea33SDavid du Colombier if(!f) {
684e887ea33SDavid du Colombier p1->from = *a;
685e887ea33SDavid du Colombier *a = zprog.from;
686e887ea33SDavid du Colombier a->type = rn;
687e887ea33SDavid du Colombier if(v->etype == TUCHAR)
688e887ea33SDavid du Colombier p1->as = AMOVB;
689e887ea33SDavid du Colombier if(v->etype == TUSHORT)
690e887ea33SDavid du Colombier p1->as = AMOVW;
691e887ea33SDavid du Colombier }
692e887ea33SDavid du Colombier if(debug['R'])
693e887ea33SDavid du Colombier print("%P\t.a%P\n", p, p1);
694e887ea33SDavid du Colombier }
695e887ea33SDavid du Colombier
696e887ea33SDavid du Colombier ulong
doregbits(int r)697e887ea33SDavid du Colombier doregbits(int r)
698e887ea33SDavid du Colombier {
699e887ea33SDavid du Colombier ulong b;
700e887ea33SDavid du Colombier
701e887ea33SDavid du Colombier b = 0;
702e887ea33SDavid du Colombier if(r >= D_INDIR)
703e887ea33SDavid du Colombier r -= D_INDIR;
704e887ea33SDavid du Colombier if(r >= D_AX && r <= D_R15)
705e887ea33SDavid du Colombier b |= RtoB(r);
706e887ea33SDavid du Colombier else
707e887ea33SDavid du Colombier if(r >= D_AL && r <= D_R15B)
708e887ea33SDavid du Colombier b |= RtoB(r-D_AL+D_AX);
709e887ea33SDavid du Colombier else
710e887ea33SDavid du Colombier if(r >= D_AH && r <= D_BH)
711e887ea33SDavid du Colombier b |= RtoB(r-D_AH+D_AX);
712e887ea33SDavid du Colombier else
713e887ea33SDavid du Colombier if(r >= D_X0 && r <= D_X0+15)
714e887ea33SDavid du Colombier b |= FtoB(r);
715e887ea33SDavid du Colombier return b;
716e887ea33SDavid du Colombier }
717e887ea33SDavid du Colombier
718e887ea33SDavid du Colombier Bits
mkvar(Reg * r,Adr * a)719e887ea33SDavid du Colombier mkvar(Reg *r, Adr *a)
720e887ea33SDavid du Colombier {
721e887ea33SDavid du Colombier Var *v;
722e887ea33SDavid du Colombier int i, t, n, et, z;
723e887ea33SDavid du Colombier long o;
724e887ea33SDavid du Colombier Bits bit;
725e887ea33SDavid du Colombier Sym *s;
726e887ea33SDavid du Colombier
727e887ea33SDavid du Colombier /*
728e887ea33SDavid du Colombier * mark registers used
729e887ea33SDavid du Colombier */
730e887ea33SDavid du Colombier t = a->type;
731e887ea33SDavid du Colombier r->regu |= doregbits(t);
732e887ea33SDavid du Colombier r->regu |= doregbits(a->index);
733e887ea33SDavid du Colombier
734e887ea33SDavid du Colombier switch(t) {
735e887ea33SDavid du Colombier default:
736e887ea33SDavid du Colombier goto none;
737e887ea33SDavid du Colombier case D_ADDR:
738e887ea33SDavid du Colombier a->type = a->index;
739e887ea33SDavid du Colombier bit = mkvar(r, a);
740e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
741e887ea33SDavid du Colombier addrs.b[z] |= bit.b[z];
742e887ea33SDavid du Colombier a->type = t;
743e887ea33SDavid du Colombier goto none;
744e887ea33SDavid du Colombier case D_EXTERN:
745e887ea33SDavid du Colombier case D_STATIC:
746e887ea33SDavid du Colombier case D_PARAM:
747e887ea33SDavid du Colombier case D_AUTO:
748e887ea33SDavid du Colombier n = t;
749e887ea33SDavid du Colombier break;
750e887ea33SDavid du Colombier }
751e887ea33SDavid du Colombier s = a->sym;
752e887ea33SDavid du Colombier if(s == S)
753e887ea33SDavid du Colombier goto none;
754e887ea33SDavid du Colombier if(s->name[0] == '.')
755e887ea33SDavid du Colombier goto none;
756e887ea33SDavid du Colombier et = a->etype;
757e887ea33SDavid du Colombier o = a->offset;
758e887ea33SDavid du Colombier v = var;
759e887ea33SDavid du Colombier for(i=0; i<nvar; i++) {
760e887ea33SDavid du Colombier if(s == v->sym)
761e887ea33SDavid du Colombier if(n == v->name)
762e887ea33SDavid du Colombier if(o == v->offset)
763e887ea33SDavid du Colombier goto out;
764e887ea33SDavid du Colombier v++;
765e887ea33SDavid du Colombier }
766e887ea33SDavid du Colombier if(nvar >= NVAR) {
767e887ea33SDavid du Colombier if(debug['w'] > 1 && s)
768e887ea33SDavid du Colombier warn(Z, "variable not optimized: %s", s->name);
769e887ea33SDavid du Colombier goto none;
770e887ea33SDavid du Colombier }
771e887ea33SDavid du Colombier i = nvar;
772e887ea33SDavid du Colombier nvar++;
773e887ea33SDavid du Colombier v = &var[i];
774e887ea33SDavid du Colombier v->sym = s;
775e887ea33SDavid du Colombier v->offset = o;
776e887ea33SDavid du Colombier v->name = n;
777e887ea33SDavid du Colombier v->etype = et;
778e887ea33SDavid du Colombier if(debug['R'])
779e887ea33SDavid du Colombier print("bit=%2d et=%2d %D\n", i, et, a);
780e887ea33SDavid du Colombier
781e887ea33SDavid du Colombier out:
782e887ea33SDavid du Colombier bit = blsh(i);
783e887ea33SDavid du Colombier if(n == D_EXTERN || n == D_STATIC)
784e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
785e887ea33SDavid du Colombier externs.b[z] |= bit.b[z];
786e887ea33SDavid du Colombier if(n == D_PARAM)
787e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
788e887ea33SDavid du Colombier params.b[z] |= bit.b[z];
789e887ea33SDavid du Colombier if(v->etype != et || !(typechlpfd[et] || typev[et])) /* funny punning */
790e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
791e887ea33SDavid du Colombier addrs.b[z] |= bit.b[z];
792e887ea33SDavid du Colombier return bit;
793e887ea33SDavid du Colombier
794e887ea33SDavid du Colombier none:
795e887ea33SDavid du Colombier return zbits;
796e887ea33SDavid du Colombier }
797e887ea33SDavid du Colombier
798e887ea33SDavid du Colombier void
prop(Reg * r,Bits ref,Bits cal)799e887ea33SDavid du Colombier prop(Reg *r, Bits ref, Bits cal)
800e887ea33SDavid du Colombier {
801e887ea33SDavid du Colombier Reg *r1, *r2;
802e887ea33SDavid du Colombier int z;
803e887ea33SDavid du Colombier
804e887ea33SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->p1) {
805e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
806e887ea33SDavid du Colombier ref.b[z] |= r1->refahead.b[z];
807e887ea33SDavid du Colombier if(ref.b[z] != r1->refahead.b[z]) {
808e887ea33SDavid du Colombier r1->refahead.b[z] = ref.b[z];
809e887ea33SDavid du Colombier change++;
810e887ea33SDavid du Colombier }
811e887ea33SDavid du Colombier cal.b[z] |= r1->calahead.b[z];
812e887ea33SDavid du Colombier if(cal.b[z] != r1->calahead.b[z]) {
813e887ea33SDavid du Colombier r1->calahead.b[z] = cal.b[z];
814e887ea33SDavid du Colombier change++;
815e887ea33SDavid du Colombier }
816e887ea33SDavid du Colombier }
817e887ea33SDavid du Colombier switch(r1->prog->as) {
818e887ea33SDavid du Colombier case ACALL:
819e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
820e887ea33SDavid du Colombier cal.b[z] |= ref.b[z] | externs.b[z];
821e887ea33SDavid du Colombier ref.b[z] = 0;
822e887ea33SDavid du Colombier }
823e887ea33SDavid du Colombier break;
824e887ea33SDavid du Colombier
825e887ea33SDavid du Colombier case ATEXT:
826e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
827e887ea33SDavid du Colombier cal.b[z] = 0;
828e887ea33SDavid du Colombier ref.b[z] = 0;
829e887ea33SDavid du Colombier }
830e887ea33SDavid du Colombier break;
831e887ea33SDavid du Colombier
832e887ea33SDavid du Colombier case ARET:
833e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
834e887ea33SDavid du Colombier cal.b[z] = externs.b[z];
835e887ea33SDavid du Colombier ref.b[z] = 0;
836e887ea33SDavid du Colombier }
837e887ea33SDavid du Colombier }
838e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
839e887ea33SDavid du Colombier ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
840e887ea33SDavid du Colombier r1->use1.b[z] | r1->use2.b[z];
841e887ea33SDavid du Colombier cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
842e887ea33SDavid du Colombier r1->refbehind.b[z] = ref.b[z];
843e887ea33SDavid du Colombier r1->calbehind.b[z] = cal.b[z];
844e887ea33SDavid du Colombier }
845e887ea33SDavid du Colombier if(r1->active)
846e887ea33SDavid du Colombier break;
847e887ea33SDavid du Colombier r1->active = 1;
848e887ea33SDavid du Colombier }
849e887ea33SDavid du Colombier for(; r != r1; r = r->p1)
850e887ea33SDavid du Colombier for(r2 = r->p2; r2 != R; r2 = r2->p2link)
851e887ea33SDavid du Colombier prop(r2, r->refbehind, r->calbehind);
852e887ea33SDavid du Colombier }
853e887ea33SDavid du Colombier
854e887ea33SDavid du Colombier /*
855e887ea33SDavid du Colombier * find looping structure
856e887ea33SDavid du Colombier *
857e887ea33SDavid du Colombier * 1) find reverse postordering
858e887ea33SDavid du Colombier * 2) find approximate dominators,
859e887ea33SDavid du Colombier * the actual dominators if the flow graph is reducible
860e887ea33SDavid du Colombier * otherwise, dominators plus some other non-dominators.
861e887ea33SDavid du Colombier * See Matthew S. Hecht and Jeffrey D. Ullman,
862e887ea33SDavid du Colombier * "Analysis of a Simple Algorithm for Global Data Flow Problems",
863e887ea33SDavid du Colombier * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
864e887ea33SDavid du Colombier * Oct. 1-3, 1973, pp. 207-217.
865e887ea33SDavid du Colombier * 3) find all nodes with a predecessor dominated by the current node.
866e887ea33SDavid du Colombier * such a node is a loop head.
867e887ea33SDavid du Colombier * recursively, all preds with a greater rpo number are in the loop
868e887ea33SDavid du Colombier */
869e887ea33SDavid du Colombier long
postorder(Reg * r,Reg ** rpo2r,long n)870e887ea33SDavid du Colombier postorder(Reg *r, Reg **rpo2r, long n)
871e887ea33SDavid du Colombier {
872e887ea33SDavid du Colombier Reg *r1;
873e887ea33SDavid du Colombier
874e887ea33SDavid du Colombier r->rpo = 1;
875e887ea33SDavid du Colombier r1 = r->s1;
876e887ea33SDavid du Colombier if(r1 && !r1->rpo)
877e887ea33SDavid du Colombier n = postorder(r1, rpo2r, n);
878e887ea33SDavid du Colombier r1 = r->s2;
879e887ea33SDavid du Colombier if(r1 && !r1->rpo)
880e887ea33SDavid du Colombier n = postorder(r1, rpo2r, n);
881e887ea33SDavid du Colombier rpo2r[n] = r;
882e887ea33SDavid du Colombier n++;
883e887ea33SDavid du Colombier return n;
884e887ea33SDavid du Colombier }
885e887ea33SDavid du Colombier
886e887ea33SDavid du Colombier long
rpolca(long * idom,long rpo1,long rpo2)887e887ea33SDavid du Colombier rpolca(long *idom, long rpo1, long rpo2)
888e887ea33SDavid du Colombier {
889e887ea33SDavid du Colombier long t;
890e887ea33SDavid du Colombier
891e887ea33SDavid du Colombier if(rpo1 == -1)
892e887ea33SDavid du Colombier return rpo2;
893e887ea33SDavid du Colombier while(rpo1 != rpo2){
894e887ea33SDavid du Colombier if(rpo1 > rpo2){
895e887ea33SDavid du Colombier t = rpo2;
896e887ea33SDavid du Colombier rpo2 = rpo1;
897e887ea33SDavid du Colombier rpo1 = t;
898e887ea33SDavid du Colombier }
899e887ea33SDavid du Colombier while(rpo1 < rpo2){
900e887ea33SDavid du Colombier t = idom[rpo2];
901e887ea33SDavid du Colombier if(t >= rpo2)
902e887ea33SDavid du Colombier fatal(Z, "bad idom");
903e887ea33SDavid du Colombier rpo2 = t;
904e887ea33SDavid du Colombier }
905e887ea33SDavid du Colombier }
906e887ea33SDavid du Colombier return rpo1;
907e887ea33SDavid du Colombier }
908e887ea33SDavid du Colombier
909e887ea33SDavid du Colombier int
doms(long * idom,long r,long s)910e887ea33SDavid du Colombier doms(long *idom, long r, long s)
911e887ea33SDavid du Colombier {
912e887ea33SDavid du Colombier while(s > r)
913e887ea33SDavid du Colombier s = idom[s];
914e887ea33SDavid du Colombier return s == r;
915e887ea33SDavid du Colombier }
916e887ea33SDavid du Colombier
917e887ea33SDavid du Colombier int
loophead(long * idom,Reg * r)918e887ea33SDavid du Colombier loophead(long *idom, Reg *r)
919e887ea33SDavid du Colombier {
920e887ea33SDavid du Colombier long src;
921e887ea33SDavid du Colombier
922e887ea33SDavid du Colombier src = r->rpo;
923e887ea33SDavid du Colombier if(r->p1 != R && doms(idom, src, r->p1->rpo))
924e887ea33SDavid du Colombier return 1;
925e887ea33SDavid du Colombier for(r = r->p2; r != R; r = r->p2link)
926e887ea33SDavid du Colombier if(doms(idom, src, r->rpo))
927e887ea33SDavid du Colombier return 1;
928e887ea33SDavid du Colombier return 0;
929e887ea33SDavid du Colombier }
930e887ea33SDavid du Colombier
931e887ea33SDavid du Colombier void
loopmark(Reg ** rpo2r,long head,Reg * r)932e887ea33SDavid du Colombier loopmark(Reg **rpo2r, long head, Reg *r)
933e887ea33SDavid du Colombier {
934e887ea33SDavid du Colombier if(r->rpo < head || r->active == head)
935e887ea33SDavid du Colombier return;
936e887ea33SDavid du Colombier r->active = head;
937e887ea33SDavid du Colombier r->loop += LOOP;
938e887ea33SDavid du Colombier if(r->p1 != R)
939e887ea33SDavid du Colombier loopmark(rpo2r, head, r->p1);
940e887ea33SDavid du Colombier for(r = r->p2; r != R; r = r->p2link)
941e887ea33SDavid du Colombier loopmark(rpo2r, head, r);
942e887ea33SDavid du Colombier }
943e887ea33SDavid du Colombier
944e887ea33SDavid du Colombier void
loopit(Reg * r,long nr)945e887ea33SDavid du Colombier loopit(Reg *r, long nr)
946e887ea33SDavid du Colombier {
947e887ea33SDavid du Colombier Reg *r1;
948e887ea33SDavid du Colombier long i, d, me;
949e887ea33SDavid du Colombier
950e887ea33SDavid du Colombier if(nr > maxnr) {
951e887ea33SDavid du Colombier rpo2r = alloc(nr * sizeof(Reg*));
952e887ea33SDavid du Colombier idom = alloc(nr * sizeof(long));
953e887ea33SDavid du Colombier maxnr = nr;
954e887ea33SDavid du Colombier }
955e887ea33SDavid du Colombier
956e887ea33SDavid du Colombier d = postorder(r, rpo2r, 0);
957e887ea33SDavid du Colombier if(d > nr)
958e887ea33SDavid du Colombier fatal(Z, "too many reg nodes");
959e887ea33SDavid du Colombier nr = d;
960e887ea33SDavid du Colombier for(i = 0; i < nr / 2; i++){
961e887ea33SDavid du Colombier r1 = rpo2r[i];
962e887ea33SDavid du Colombier rpo2r[i] = rpo2r[nr - 1 - i];
963e887ea33SDavid du Colombier rpo2r[nr - 1 - i] = r1;
964e887ea33SDavid du Colombier }
965e887ea33SDavid du Colombier for(i = 0; i < nr; i++)
966e887ea33SDavid du Colombier rpo2r[i]->rpo = i;
967e887ea33SDavid du Colombier
968e887ea33SDavid du Colombier idom[0] = 0;
969e887ea33SDavid du Colombier for(i = 0; i < nr; i++){
970e887ea33SDavid du Colombier r1 = rpo2r[i];
971e887ea33SDavid du Colombier me = r1->rpo;
972e887ea33SDavid du Colombier d = -1;
973e887ea33SDavid du Colombier if(r1->p1 != R && r1->p1->rpo < me)
974e887ea33SDavid du Colombier d = r1->p1->rpo;
975e887ea33SDavid du Colombier for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
976e887ea33SDavid du Colombier if(r1->rpo < me)
977e887ea33SDavid du Colombier d = rpolca(idom, d, r1->rpo);
978e887ea33SDavid du Colombier idom[i] = d;
979e887ea33SDavid du Colombier }
980e887ea33SDavid du Colombier
981e887ea33SDavid du Colombier for(i = 0; i < nr; i++){
982e887ea33SDavid du Colombier r1 = rpo2r[i];
983e887ea33SDavid du Colombier r1->loop++;
984e887ea33SDavid du Colombier if(r1->p2 != R && loophead(idom, r1))
985e887ea33SDavid du Colombier loopmark(rpo2r, i, r1);
986e887ea33SDavid du Colombier }
987e887ea33SDavid du Colombier }
988e887ea33SDavid du Colombier
989e887ea33SDavid du Colombier void
synch(Reg * r,Bits dif)990e887ea33SDavid du Colombier synch(Reg *r, Bits dif)
991e887ea33SDavid du Colombier {
992e887ea33SDavid du Colombier Reg *r1;
993e887ea33SDavid du Colombier int z;
994e887ea33SDavid du Colombier
995e887ea33SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->s1) {
996e887ea33SDavid du Colombier for(z=0; z<BITS; z++) {
997e887ea33SDavid du Colombier dif.b[z] = (dif.b[z] &
998e887ea33SDavid du Colombier ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
999e887ea33SDavid du Colombier r1->set.b[z] | r1->regdiff.b[z];
1000e887ea33SDavid du Colombier if(dif.b[z] != r1->regdiff.b[z]) {
1001e887ea33SDavid du Colombier r1->regdiff.b[z] = dif.b[z];
1002e887ea33SDavid du Colombier change++;
1003e887ea33SDavid du Colombier }
1004e887ea33SDavid du Colombier }
1005e887ea33SDavid du Colombier if(r1->active)
1006e887ea33SDavid du Colombier break;
1007e887ea33SDavid du Colombier r1->active = 1;
1008e887ea33SDavid du Colombier for(z=0; z<BITS; z++)
1009e887ea33SDavid du Colombier dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
1010e887ea33SDavid du Colombier if(r1->s2 != R)
1011e887ea33SDavid du Colombier synch(r1->s2, dif);
1012e887ea33SDavid du Colombier }
1013e887ea33SDavid du Colombier }
1014e887ea33SDavid du Colombier
1015e887ea33SDavid du Colombier ulong
allreg(ulong b,Rgn * r)1016e887ea33SDavid du Colombier allreg(ulong b, Rgn *r)
1017e887ea33SDavid du Colombier {
1018e887ea33SDavid du Colombier Var *v;
1019e887ea33SDavid du Colombier int i;
1020e887ea33SDavid du Colombier
1021e887ea33SDavid du Colombier v = var + r->varno;
1022e887ea33SDavid du Colombier r->regno = 0;
1023e887ea33SDavid du Colombier switch(v->etype) {
1024e887ea33SDavid du Colombier
1025e887ea33SDavid du Colombier default:
1026e887ea33SDavid du Colombier diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
1027e887ea33SDavid du Colombier break;
1028e887ea33SDavid du Colombier
1029e887ea33SDavid du Colombier case TCHAR:
1030e887ea33SDavid du Colombier case TUCHAR:
1031e887ea33SDavid du Colombier case TSHORT:
1032e887ea33SDavid du Colombier case TUSHORT:
1033e887ea33SDavid du Colombier case TINT:
1034e887ea33SDavid du Colombier case TUINT:
1035e887ea33SDavid du Colombier case TLONG:
1036e887ea33SDavid du Colombier case TULONG:
1037e887ea33SDavid du Colombier case TVLONG:
1038e887ea33SDavid du Colombier case TUVLONG:
1039e887ea33SDavid du Colombier case TIND:
1040e887ea33SDavid du Colombier case TARRAY:
1041e887ea33SDavid du Colombier i = BtoR(~b);
1042e887ea33SDavid du Colombier if(i && r->cost > 0) {
1043e887ea33SDavid du Colombier r->regno = i;
1044e887ea33SDavid du Colombier return RtoB(i);
1045e887ea33SDavid du Colombier }
1046e887ea33SDavid du Colombier break;
1047e887ea33SDavid du Colombier
1048e887ea33SDavid du Colombier case TDOUBLE:
1049e887ea33SDavid du Colombier case TFLOAT:
1050e887ea33SDavid du Colombier i = BtoF(~b);
1051e887ea33SDavid du Colombier if(i && r->cost > 0) {
1052e887ea33SDavid du Colombier r->regno = i;
1053e887ea33SDavid du Colombier return FtoB(i);
1054e887ea33SDavid du Colombier }
1055e887ea33SDavid du Colombier break;
1056e887ea33SDavid du Colombier }
1057e887ea33SDavid du Colombier return 0;
1058e887ea33SDavid du Colombier }
1059e887ea33SDavid du Colombier
1060e887ea33SDavid du Colombier void
paint1(Reg * r,int bn)1061e887ea33SDavid du Colombier paint1(Reg *r, int bn)
1062e887ea33SDavid du Colombier {
1063e887ea33SDavid du Colombier Reg *r1;
1064e887ea33SDavid du Colombier Prog *p;
1065e887ea33SDavid du Colombier int z;
1066e887ea33SDavid du Colombier ulong bb;
1067e887ea33SDavid du Colombier
1068e887ea33SDavid du Colombier z = bn/32;
1069e887ea33SDavid du Colombier bb = 1L<<(bn%32);
1070e887ea33SDavid du Colombier if(r->act.b[z] & bb)
1071e887ea33SDavid du Colombier return;
1072e887ea33SDavid du Colombier for(;;) {
1073e887ea33SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1074e887ea33SDavid du Colombier break;
1075e887ea33SDavid du Colombier r1 = r->p1;
1076e887ea33SDavid du Colombier if(r1 == R)
1077e887ea33SDavid du Colombier break;
1078e887ea33SDavid du Colombier if(!(r1->refahead.b[z] & bb))
1079e887ea33SDavid du Colombier break;
1080e887ea33SDavid du Colombier if(r1->act.b[z] & bb)
1081e887ea33SDavid du Colombier break;
1082e887ea33SDavid du Colombier r = r1;
1083e887ea33SDavid du Colombier }
1084e887ea33SDavid du Colombier
1085e887ea33SDavid du Colombier if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
1086e887ea33SDavid du Colombier change -= CLOAD * r->loop;
1087e887ea33SDavid du Colombier if(debug['R'] && debug['v'])
1088e887ea33SDavid du Colombier print("%ld%P\tld %B $%d\n", r->loop,
1089e887ea33SDavid du Colombier r->prog, blsh(bn), change);
1090e887ea33SDavid du Colombier }
1091e887ea33SDavid du Colombier for(;;) {
1092e887ea33SDavid du Colombier r->act.b[z] |= bb;
1093e887ea33SDavid du Colombier p = r->prog;
1094e887ea33SDavid du Colombier
1095e887ea33SDavid du Colombier if(r->use1.b[z] & bb) {
1096e887ea33SDavid du Colombier change += CREF * r->loop;
1097e887ea33SDavid du Colombier if(debug['R'] && debug['v'])
1098e887ea33SDavid du Colombier print("%ld%P\tu1 %B $%d\n", r->loop,
1099e887ea33SDavid du Colombier p, blsh(bn), change);
1100e887ea33SDavid du Colombier }
1101e887ea33SDavid du Colombier
1102e887ea33SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) {
1103e887ea33SDavid du Colombier change += CREF * r->loop;
1104e887ea33SDavid du Colombier if(debug['R'] && debug['v'])
1105e887ea33SDavid du Colombier print("%ld%P\tu2 %B $%d\n", r->loop,
1106e887ea33SDavid du Colombier p, blsh(bn), change);
1107e887ea33SDavid du Colombier }
1108e887ea33SDavid du Colombier
1109e887ea33SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb) {
1110e887ea33SDavid du Colombier change -= CLOAD * r->loop;
1111e887ea33SDavid du Colombier if(debug['R'] && debug['v'])
1112e887ea33SDavid du Colombier print("%ld%P\tst %B $%d\n", r->loop,
1113e887ea33SDavid du Colombier p, blsh(bn), change);
1114e887ea33SDavid du Colombier }
1115e887ea33SDavid du Colombier
1116e887ea33SDavid du Colombier if(r->refbehind.b[z] & bb)
1117e887ea33SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1118e887ea33SDavid du Colombier if(r1->refahead.b[z] & bb)
1119e887ea33SDavid du Colombier paint1(r1, bn);
1120e887ea33SDavid du Colombier
1121e887ea33SDavid du Colombier if(!(r->refahead.b[z] & bb))
1122e887ea33SDavid du Colombier break;
1123e887ea33SDavid du Colombier r1 = r->s2;
1124e887ea33SDavid du Colombier if(r1 != R)
1125e887ea33SDavid du Colombier if(r1->refbehind.b[z] & bb)
1126e887ea33SDavid du Colombier paint1(r1, bn);
1127e887ea33SDavid du Colombier r = r->s1;
1128e887ea33SDavid du Colombier if(r == R)
1129e887ea33SDavid du Colombier break;
1130e887ea33SDavid du Colombier if(r->act.b[z] & bb)
1131e887ea33SDavid du Colombier break;
1132e887ea33SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1133e887ea33SDavid du Colombier break;
1134e887ea33SDavid du Colombier }
1135e887ea33SDavid du Colombier }
1136e887ea33SDavid du Colombier
1137e887ea33SDavid du Colombier ulong
regset(Reg * r,ulong bb)1138e887ea33SDavid du Colombier regset(Reg *r, ulong bb)
1139e887ea33SDavid du Colombier {
1140e887ea33SDavid du Colombier ulong b, set;
1141e887ea33SDavid du Colombier Adr v;
1142e887ea33SDavid du Colombier int c;
1143e887ea33SDavid du Colombier
1144e887ea33SDavid du Colombier set = 0;
1145e887ea33SDavid du Colombier v = zprog.from;
1146e887ea33SDavid du Colombier while(b = bb & ~(bb-1)) {
1147e887ea33SDavid du Colombier v.type = b & 0xFFFF? BtoR(b): BtoF(b);
1148e887ea33SDavid du Colombier if(v.type == 0)
1149e887ea33SDavid du Colombier diag(Z, "zero v.type for %#lux", b);
1150e887ea33SDavid du Colombier c = copyu(r->prog, &v, A);
1151e887ea33SDavid du Colombier if(c == 3)
1152e887ea33SDavid du Colombier set |= b;
1153e887ea33SDavid du Colombier bb &= ~b;
1154e887ea33SDavid du Colombier }
1155e887ea33SDavid du Colombier return set;
1156e887ea33SDavid du Colombier }
1157e887ea33SDavid du Colombier
1158e887ea33SDavid du Colombier ulong
reguse(Reg * r,ulong bb)1159e887ea33SDavid du Colombier reguse(Reg *r, ulong bb)
1160e887ea33SDavid du Colombier {
1161e887ea33SDavid du Colombier ulong b, set;
1162e887ea33SDavid du Colombier Adr v;
1163e887ea33SDavid du Colombier int c;
1164e887ea33SDavid du Colombier
1165e887ea33SDavid du Colombier set = 0;
1166e887ea33SDavid du Colombier v = zprog.from;
1167e887ea33SDavid du Colombier while(b = bb & ~(bb-1)) {
1168e887ea33SDavid du Colombier v.type = b & 0xFFFF? BtoR(b): BtoF(b);
1169e887ea33SDavid du Colombier c = copyu(r->prog, &v, A);
1170e887ea33SDavid du Colombier if(c == 1 || c == 2 || c == 4)
1171e887ea33SDavid du Colombier set |= b;
1172e887ea33SDavid du Colombier bb &= ~b;
1173e887ea33SDavid du Colombier }
1174e887ea33SDavid du Colombier return set;
1175e887ea33SDavid du Colombier }
1176e887ea33SDavid du Colombier
1177e887ea33SDavid du Colombier ulong
paint2(Reg * r,int bn)1178e887ea33SDavid du Colombier paint2(Reg *r, int bn)
1179e887ea33SDavid du Colombier {
1180e887ea33SDavid du Colombier Reg *r1;
1181e887ea33SDavid du Colombier int z;
1182e887ea33SDavid du Colombier ulong bb, vreg, x;
1183e887ea33SDavid du Colombier
1184e887ea33SDavid du Colombier z = bn/32;
1185e887ea33SDavid du Colombier bb = 1L << (bn%32);
1186e887ea33SDavid du Colombier vreg = regbits;
1187e887ea33SDavid du Colombier if(!(r->act.b[z] & bb))
1188e887ea33SDavid du Colombier return vreg;
1189e887ea33SDavid du Colombier for(;;) {
1190e887ea33SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1191e887ea33SDavid du Colombier break;
1192e887ea33SDavid du Colombier r1 = r->p1;
1193e887ea33SDavid du Colombier if(r1 == R)
1194e887ea33SDavid du Colombier break;
1195e887ea33SDavid du Colombier if(!(r1->refahead.b[z] & bb))
1196e887ea33SDavid du Colombier break;
1197e887ea33SDavid du Colombier if(!(r1->act.b[z] & bb))
1198e887ea33SDavid du Colombier break;
1199e887ea33SDavid du Colombier r = r1;
1200e887ea33SDavid du Colombier }
1201e887ea33SDavid du Colombier for(;;) {
1202e887ea33SDavid du Colombier r->act.b[z] &= ~bb;
1203e887ea33SDavid du Colombier
1204e887ea33SDavid du Colombier vreg |= r->regu;
1205e887ea33SDavid du Colombier
1206e887ea33SDavid du Colombier if(r->refbehind.b[z] & bb)
1207e887ea33SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1208e887ea33SDavid du Colombier if(r1->refahead.b[z] & bb)
1209e887ea33SDavid du Colombier vreg |= paint2(r1, bn);
1210e887ea33SDavid du Colombier
1211e887ea33SDavid du Colombier if(!(r->refahead.b[z] & bb))
1212e887ea33SDavid du Colombier break;
1213e887ea33SDavid du Colombier r1 = r->s2;
1214e887ea33SDavid du Colombier if(r1 != R)
1215e887ea33SDavid du Colombier if(r1->refbehind.b[z] & bb)
1216e887ea33SDavid du Colombier vreg |= paint2(r1, bn);
1217e887ea33SDavid du Colombier r = r->s1;
1218e887ea33SDavid du Colombier if(r == R)
1219e887ea33SDavid du Colombier break;
1220e887ea33SDavid du Colombier if(!(r->act.b[z] & bb))
1221e887ea33SDavid du Colombier break;
1222e887ea33SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1223e887ea33SDavid du Colombier break;
1224e887ea33SDavid du Colombier }
1225e887ea33SDavid du Colombier
1226e887ea33SDavid du Colombier bb = vreg;
1227e887ea33SDavid du Colombier for(; r; r=r->s1) {
1228e887ea33SDavid du Colombier x = r->regu & ~bb;
1229e887ea33SDavid du Colombier if(x) {
1230e887ea33SDavid du Colombier vreg |= reguse(r, x);
1231e887ea33SDavid du Colombier bb |= regset(r, x);
1232e887ea33SDavid du Colombier }
1233e887ea33SDavid du Colombier }
1234e887ea33SDavid du Colombier return vreg;
1235e887ea33SDavid du Colombier }
1236e887ea33SDavid du Colombier
1237e887ea33SDavid du Colombier void
paint3(Reg * r,int bn,long rb,int rn)1238e887ea33SDavid du Colombier paint3(Reg *r, int bn, long rb, int rn)
1239e887ea33SDavid du Colombier {
1240e887ea33SDavid du Colombier Reg *r1;
1241e887ea33SDavid du Colombier Prog *p;
1242e887ea33SDavid du Colombier int z;
1243e887ea33SDavid du Colombier ulong bb;
1244e887ea33SDavid du Colombier
1245e887ea33SDavid du Colombier z = bn/32;
1246e887ea33SDavid du Colombier bb = 1L << (bn%32);
1247e887ea33SDavid du Colombier if(r->act.b[z] & bb)
1248e887ea33SDavid du Colombier return;
1249e887ea33SDavid du Colombier for(;;) {
1250e887ea33SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1251e887ea33SDavid du Colombier break;
1252e887ea33SDavid du Colombier r1 = r->p1;
1253e887ea33SDavid du Colombier if(r1 == R)
1254e887ea33SDavid du Colombier break;
1255e887ea33SDavid du Colombier if(!(r1->refahead.b[z] & bb))
1256e887ea33SDavid du Colombier break;
1257e887ea33SDavid du Colombier if(r1->act.b[z] & bb)
1258e887ea33SDavid du Colombier break;
1259e887ea33SDavid du Colombier r = r1;
1260e887ea33SDavid du Colombier }
1261e887ea33SDavid du Colombier
1262e887ea33SDavid du Colombier if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
1263e887ea33SDavid du Colombier addmove(r, bn, rn, 0);
1264e887ea33SDavid du Colombier for(;;) {
1265e887ea33SDavid du Colombier r->act.b[z] |= bb;
1266e887ea33SDavid du Colombier p = r->prog;
1267e887ea33SDavid du Colombier
1268e887ea33SDavid du Colombier if(r->use1.b[z] & bb) {
1269e887ea33SDavid du Colombier if(debug['R'])
1270e887ea33SDavid du Colombier print("%P", p);
1271e887ea33SDavid du Colombier addreg(&p->from, rn);
1272e887ea33SDavid du Colombier if(debug['R'])
1273e887ea33SDavid du Colombier print("\t.c%P\n", p);
1274e887ea33SDavid du Colombier }
1275e887ea33SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) {
1276e887ea33SDavid du Colombier if(debug['R'])
1277e887ea33SDavid du Colombier print("%P", p);
1278e887ea33SDavid du Colombier addreg(&p->to, rn);
1279e887ea33SDavid du Colombier if(debug['R'])
1280e887ea33SDavid du Colombier print("\t.c%P\n", p);
1281e887ea33SDavid du Colombier }
1282e887ea33SDavid du Colombier
1283e887ea33SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb)
1284e887ea33SDavid du Colombier addmove(r, bn, rn, 1);
1285e887ea33SDavid du Colombier r->regu |= rb;
1286e887ea33SDavid du Colombier
1287e887ea33SDavid du Colombier if(r->refbehind.b[z] & bb)
1288e887ea33SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1289e887ea33SDavid du Colombier if(r1->refahead.b[z] & bb)
1290e887ea33SDavid du Colombier paint3(r1, bn, rb, rn);
1291e887ea33SDavid du Colombier
1292e887ea33SDavid du Colombier if(!(r->refahead.b[z] & bb))
1293e887ea33SDavid du Colombier break;
1294e887ea33SDavid du Colombier r1 = r->s2;
1295e887ea33SDavid du Colombier if(r1 != R)
1296e887ea33SDavid du Colombier if(r1->refbehind.b[z] & bb)
1297e887ea33SDavid du Colombier paint3(r1, bn, rb, rn);
1298e887ea33SDavid du Colombier r = r->s1;
1299e887ea33SDavid du Colombier if(r == R)
1300e887ea33SDavid du Colombier break;
1301e887ea33SDavid du Colombier if(r->act.b[z] & bb)
1302e887ea33SDavid du Colombier break;
1303e887ea33SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1304e887ea33SDavid du Colombier break;
1305e887ea33SDavid du Colombier }
1306e887ea33SDavid du Colombier }
1307e887ea33SDavid du Colombier
1308e887ea33SDavid du Colombier void
addreg(Adr * a,int rn)1309e887ea33SDavid du Colombier addreg(Adr *a, int rn)
1310e887ea33SDavid du Colombier {
1311e887ea33SDavid du Colombier
1312e887ea33SDavid du Colombier a->sym = 0;
1313e887ea33SDavid du Colombier a->offset = 0;
1314e887ea33SDavid du Colombier a->type = rn;
1315e887ea33SDavid du Colombier }
1316e887ea33SDavid du Colombier
1317e887ea33SDavid du Colombier long
RtoB(int r)1318e887ea33SDavid du Colombier RtoB(int r)
1319e887ea33SDavid du Colombier {
1320e887ea33SDavid du Colombier
1321e887ea33SDavid du Colombier if(r < D_AX || r > D_R15)
1322e887ea33SDavid du Colombier return 0;
1323e887ea33SDavid du Colombier return 1L << (r-D_AX);
1324e887ea33SDavid du Colombier }
1325e887ea33SDavid du Colombier
1326e887ea33SDavid du Colombier int
BtoR(long b)1327e887ea33SDavid du Colombier BtoR(long b)
1328e887ea33SDavid du Colombier {
1329e887ea33SDavid du Colombier
1330e887ea33SDavid du Colombier b &= 0xffffL;
1331e887ea33SDavid du Colombier if(b == 0)
1332e887ea33SDavid du Colombier return 0;
1333e887ea33SDavid du Colombier return bitno(b) + D_AX;
1334e887ea33SDavid du Colombier }
1335e887ea33SDavid du Colombier
1336e887ea33SDavid du Colombier /*
1337e887ea33SDavid du Colombier * bit reg
1338e887ea33SDavid du Colombier * 16 X5
1339e887ea33SDavid du Colombier * 17 X6
1340e887ea33SDavid du Colombier * 18 X7
1341e887ea33SDavid du Colombier */
1342e887ea33SDavid du Colombier long
FtoB(int f)1343e887ea33SDavid du Colombier FtoB(int f)
1344e887ea33SDavid du Colombier {
1345e887ea33SDavid du Colombier if(f < FREGMIN || f > FREGEXT)
1346e887ea33SDavid du Colombier return 0;
1347e887ea33SDavid du Colombier return 1L << (f - FREGMIN + 16);
1348e887ea33SDavid du Colombier }
1349e887ea33SDavid du Colombier
1350e887ea33SDavid du Colombier int
BtoF(long b)1351e887ea33SDavid du Colombier BtoF(long b)
1352e887ea33SDavid du Colombier {
1353e887ea33SDavid du Colombier
1354e887ea33SDavid du Colombier b &= 0x70000L;
1355e887ea33SDavid du Colombier if(b == 0)
1356e887ea33SDavid du Colombier return 0;
1357e887ea33SDavid du Colombier return bitno(b) - 16 + FREGMIN;
1358e887ea33SDavid du Colombier }
1359