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