1*ce95e1b3SDavid du Colombier #include "gc.h"
2*ce95e1b3SDavid du Colombier
3*ce95e1b3SDavid du Colombier void addsplits(void);
4*ce95e1b3SDavid du Colombier
5*ce95e1b3SDavid du Colombier Reg*
rega(void)6*ce95e1b3SDavid du Colombier rega(void)
7*ce95e1b3SDavid du Colombier {
8*ce95e1b3SDavid du Colombier Reg *r;
9*ce95e1b3SDavid du Colombier
10*ce95e1b3SDavid du Colombier r = freer;
11*ce95e1b3SDavid du Colombier if(r == R) {
12*ce95e1b3SDavid du Colombier r = alloc(sizeof(*r));
13*ce95e1b3SDavid du Colombier } else
14*ce95e1b3SDavid du Colombier freer = r->link;
15*ce95e1b3SDavid du Colombier
16*ce95e1b3SDavid du Colombier *r = zreg;
17*ce95e1b3SDavid du Colombier return r;
18*ce95e1b3SDavid du Colombier }
19*ce95e1b3SDavid du Colombier
20*ce95e1b3SDavid du Colombier int
rcmp(void * a1,void * a2)21*ce95e1b3SDavid du Colombier rcmp(void *a1, void *a2)
22*ce95e1b3SDavid du Colombier {
23*ce95e1b3SDavid du Colombier Rgn *p1, *p2;
24*ce95e1b3SDavid du Colombier int c1, c2;
25*ce95e1b3SDavid du Colombier
26*ce95e1b3SDavid du Colombier p1 = (Rgn*)a1;
27*ce95e1b3SDavid du Colombier p2 = (Rgn*)a2;
28*ce95e1b3SDavid du Colombier c1 = p2->cost;
29*ce95e1b3SDavid du Colombier c2 = p1->cost;
30*ce95e1b3SDavid du Colombier if(c1 -= c2)
31*ce95e1b3SDavid du Colombier return c1;
32*ce95e1b3SDavid du Colombier return p2->varno - p1->varno;
33*ce95e1b3SDavid du Colombier }
34*ce95e1b3SDavid du Colombier
35*ce95e1b3SDavid du Colombier void
regopt(Prog * p)36*ce95e1b3SDavid du Colombier regopt(Prog *p)
37*ce95e1b3SDavid du Colombier {
38*ce95e1b3SDavid du Colombier Reg *r, *r1, *r2;
39*ce95e1b3SDavid du Colombier Prog *p1;
40*ce95e1b3SDavid du Colombier int i, z;
41*ce95e1b3SDavid du Colombier long initpc, val, npc;
42*ce95e1b3SDavid du Colombier ulong vreg;
43*ce95e1b3SDavid du Colombier Bits bit;
44*ce95e1b3SDavid du Colombier struct
45*ce95e1b3SDavid du Colombier {
46*ce95e1b3SDavid du Colombier long m;
47*ce95e1b3SDavid du Colombier long c;
48*ce95e1b3SDavid du Colombier Reg* p;
49*ce95e1b3SDavid du Colombier } log5[6], *lp;
50*ce95e1b3SDavid du Colombier
51*ce95e1b3SDavid du Colombier firstr = R;
52*ce95e1b3SDavid du Colombier lastr = R;
53*ce95e1b3SDavid du Colombier nvar = 0;
54*ce95e1b3SDavid du Colombier regbits = 0;
55*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
56*ce95e1b3SDavid du Colombier externs.b[z] = 0;
57*ce95e1b3SDavid du Colombier params.b[z] = 0;
58*ce95e1b3SDavid du Colombier consts.b[z] = 0;
59*ce95e1b3SDavid du Colombier addrs.b[z] = 0;
60*ce95e1b3SDavid du Colombier }
61*ce95e1b3SDavid du Colombier
62*ce95e1b3SDavid du Colombier /*
63*ce95e1b3SDavid du Colombier * pass 1
64*ce95e1b3SDavid du Colombier * build aux data structure
65*ce95e1b3SDavid du Colombier * allocate pcs
66*ce95e1b3SDavid du Colombier * find use and set of variables
67*ce95e1b3SDavid du Colombier */
68*ce95e1b3SDavid du Colombier val = 5L * 5L * 5L * 5L * 5L;
69*ce95e1b3SDavid du Colombier lp = log5;
70*ce95e1b3SDavid du Colombier for(i=0; i<5; i++) {
71*ce95e1b3SDavid du Colombier lp->m = val;
72*ce95e1b3SDavid du Colombier lp->c = 0;
73*ce95e1b3SDavid du Colombier lp->p = R;
74*ce95e1b3SDavid du Colombier val /= 5L;
75*ce95e1b3SDavid du Colombier lp++;
76*ce95e1b3SDavid du Colombier }
77*ce95e1b3SDavid du Colombier val = 0;
78*ce95e1b3SDavid du Colombier for(; p != P; p = p->link) {
79*ce95e1b3SDavid du Colombier switch(p->as) {
80*ce95e1b3SDavid du Colombier case ADATA:
81*ce95e1b3SDavid du Colombier case AGLOBL:
82*ce95e1b3SDavid du Colombier case ANAME:
83*ce95e1b3SDavid du Colombier case ASIGNAME:
84*ce95e1b3SDavid du Colombier continue;
85*ce95e1b3SDavid du Colombier }
86*ce95e1b3SDavid du Colombier r = rega();
87*ce95e1b3SDavid du Colombier if(firstr == R) {
88*ce95e1b3SDavid du Colombier firstr = r;
89*ce95e1b3SDavid du Colombier lastr = r;
90*ce95e1b3SDavid du Colombier } else {
91*ce95e1b3SDavid du Colombier lastr->link = r;
92*ce95e1b3SDavid du Colombier r->p1 = lastr;
93*ce95e1b3SDavid du Colombier lastr->s1 = r;
94*ce95e1b3SDavid du Colombier lastr = r;
95*ce95e1b3SDavid du Colombier }
96*ce95e1b3SDavid du Colombier r->prog = p;
97*ce95e1b3SDavid du Colombier r->pc = val;
98*ce95e1b3SDavid du Colombier val++;
99*ce95e1b3SDavid du Colombier
100*ce95e1b3SDavid du Colombier lp = log5;
101*ce95e1b3SDavid du Colombier for(i=0; i<5; i++) {
102*ce95e1b3SDavid du Colombier lp->c--;
103*ce95e1b3SDavid du Colombier if(lp->c <= 0) {
104*ce95e1b3SDavid du Colombier lp->c = lp->m;
105*ce95e1b3SDavid du Colombier if(lp->p != R)
106*ce95e1b3SDavid du Colombier lp->p->log5 = r;
107*ce95e1b3SDavid du Colombier lp->p = r;
108*ce95e1b3SDavid du Colombier (lp+1)->c = 0;
109*ce95e1b3SDavid du Colombier break;
110*ce95e1b3SDavid du Colombier }
111*ce95e1b3SDavid du Colombier lp++;
112*ce95e1b3SDavid du Colombier }
113*ce95e1b3SDavid du Colombier
114*ce95e1b3SDavid du Colombier r1 = r->p1;
115*ce95e1b3SDavid du Colombier if(r1 != R)
116*ce95e1b3SDavid du Colombier switch(r1->prog->as) {
117*ce95e1b3SDavid du Colombier case ARET:
118*ce95e1b3SDavid du Colombier case AJMP:
119*ce95e1b3SDavid du Colombier r->p1 = R;
120*ce95e1b3SDavid du Colombier r1->s1 = R;
121*ce95e1b3SDavid du Colombier }
122*ce95e1b3SDavid du Colombier
123*ce95e1b3SDavid du Colombier /*
124*ce95e1b3SDavid du Colombier * left side always read
125*ce95e1b3SDavid du Colombier */
126*ce95e1b3SDavid du Colombier bit = mkvar(&p->from, p->as==AMOVW || p->as==AMOV);
127*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
128*ce95e1b3SDavid du Colombier r->use1.b[z] |= bit.b[z];
129*ce95e1b3SDavid du Colombier
130*ce95e1b3SDavid du Colombier /*
131*ce95e1b3SDavid du Colombier * right side depends on opcode
132*ce95e1b3SDavid du Colombier */
133*ce95e1b3SDavid du Colombier bit = mkvar(&p->to, 0);
134*ce95e1b3SDavid du Colombier if(bany(&bit))
135*ce95e1b3SDavid du Colombier switch(p->as) {
136*ce95e1b3SDavid du Colombier default:
137*ce95e1b3SDavid du Colombier diag(Z, "reg: unknown asop: %A", p->as);
138*ce95e1b3SDavid du Colombier break;
139*ce95e1b3SDavid du Colombier
140*ce95e1b3SDavid du Colombier /*
141*ce95e1b3SDavid du Colombier * right side write
142*ce95e1b3SDavid du Colombier */
143*ce95e1b3SDavid du Colombier case ANOP:
144*ce95e1b3SDavid du Colombier case AMOVB:
145*ce95e1b3SDavid du Colombier case AMOVBU:
146*ce95e1b3SDavid du Colombier case AMOVH:
147*ce95e1b3SDavid du Colombier case AMOVHU:
148*ce95e1b3SDavid du Colombier case AMOVW:
149*ce95e1b3SDavid du Colombier case AMOV:
150*ce95e1b3SDavid du Colombier case AMOVF:
151*ce95e1b3SDavid du Colombier case AMOVD:
152*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
153*ce95e1b3SDavid du Colombier r->set.b[z] |= bit.b[z];
154*ce95e1b3SDavid du Colombier break;
155*ce95e1b3SDavid du Colombier
156*ce95e1b3SDavid du Colombier /*
157*ce95e1b3SDavid du Colombier * funny
158*ce95e1b3SDavid du Colombier */
159*ce95e1b3SDavid du Colombier case AJAL:
160*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
161*ce95e1b3SDavid du Colombier addrs.b[z] |= bit.b[z];
162*ce95e1b3SDavid du Colombier break;
163*ce95e1b3SDavid du Colombier }
164*ce95e1b3SDavid du Colombier }
165*ce95e1b3SDavid du Colombier if(firstr == R)
166*ce95e1b3SDavid du Colombier return;
167*ce95e1b3SDavid du Colombier initpc = pc - val;
168*ce95e1b3SDavid du Colombier npc = val;
169*ce95e1b3SDavid du Colombier
170*ce95e1b3SDavid du Colombier /*
171*ce95e1b3SDavid du Colombier * pass 2
172*ce95e1b3SDavid du Colombier * turn branch references to pointers
173*ce95e1b3SDavid du Colombier * build back pointers
174*ce95e1b3SDavid du Colombier */
175*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link) {
176*ce95e1b3SDavid du Colombier p = r->prog;
177*ce95e1b3SDavid du Colombier if(p->to.type == D_BRANCH) {
178*ce95e1b3SDavid du Colombier val = p->to.offset - initpc;
179*ce95e1b3SDavid du Colombier r1 = firstr;
180*ce95e1b3SDavid du Colombier while(r1 != R) {
181*ce95e1b3SDavid du Colombier r2 = r1->log5;
182*ce95e1b3SDavid du Colombier if(r2 != R && val >= r2->pc) {
183*ce95e1b3SDavid du Colombier r1 = r2;
184*ce95e1b3SDavid du Colombier continue;
185*ce95e1b3SDavid du Colombier }
186*ce95e1b3SDavid du Colombier if(r1->pc == val)
187*ce95e1b3SDavid du Colombier break;
188*ce95e1b3SDavid du Colombier r1 = r1->link;
189*ce95e1b3SDavid du Colombier }
190*ce95e1b3SDavid du Colombier if(r1 == R) {
191*ce95e1b3SDavid du Colombier nearln = p->lineno;
192*ce95e1b3SDavid du Colombier diag(Z, "ref not found\n%P", p);
193*ce95e1b3SDavid du Colombier continue;
194*ce95e1b3SDavid du Colombier }
195*ce95e1b3SDavid du Colombier if(r1 == r) {
196*ce95e1b3SDavid du Colombier nearln = p->lineno;
197*ce95e1b3SDavid du Colombier diag(Z, "ref to self\n%P", p);
198*ce95e1b3SDavid du Colombier continue;
199*ce95e1b3SDavid du Colombier }
200*ce95e1b3SDavid du Colombier r->s2 = r1;
201*ce95e1b3SDavid du Colombier r->p2link = r1->p2;
202*ce95e1b3SDavid du Colombier r1->p2 = r;
203*ce95e1b3SDavid du Colombier }
204*ce95e1b3SDavid du Colombier }
205*ce95e1b3SDavid du Colombier if(debug['R']) {
206*ce95e1b3SDavid du Colombier p = firstr->prog;
207*ce95e1b3SDavid du Colombier print("\n%L %D\n", p->lineno, &p->from);
208*ce95e1b3SDavid du Colombier }
209*ce95e1b3SDavid du Colombier
210*ce95e1b3SDavid du Colombier /*
211*ce95e1b3SDavid du Colombier * pass 2.5
212*ce95e1b3SDavid du Colombier * find looping structure
213*ce95e1b3SDavid du Colombier */
214*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link)
215*ce95e1b3SDavid du Colombier r->active = 0;
216*ce95e1b3SDavid du Colombier change = 0;
217*ce95e1b3SDavid du Colombier loopit(firstr, npc);
218*ce95e1b3SDavid du Colombier
219*ce95e1b3SDavid du Colombier /*
220*ce95e1b3SDavid du Colombier * pass 3
221*ce95e1b3SDavid du Colombier * iterate propagating usage
222*ce95e1b3SDavid du Colombier * back until flow graph is complete
223*ce95e1b3SDavid du Colombier */
224*ce95e1b3SDavid du Colombier loop1:
225*ce95e1b3SDavid du Colombier change = 0;
226*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link)
227*ce95e1b3SDavid du Colombier r->active = 0;
228*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link)
229*ce95e1b3SDavid du Colombier if(r->prog->as == ARET)
230*ce95e1b3SDavid du Colombier prop(r, zbits, zbits);
231*ce95e1b3SDavid du Colombier loop11:
232*ce95e1b3SDavid du Colombier /* pick up unreachable code */
233*ce95e1b3SDavid du Colombier i = 0;
234*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r1) {
235*ce95e1b3SDavid du Colombier r1 = r->link;
236*ce95e1b3SDavid du Colombier if(r1 && r1->active && !r->active) {
237*ce95e1b3SDavid du Colombier prop(r, zbits, zbits);
238*ce95e1b3SDavid du Colombier i = 1;
239*ce95e1b3SDavid du Colombier }
240*ce95e1b3SDavid du Colombier }
241*ce95e1b3SDavid du Colombier if(i)
242*ce95e1b3SDavid du Colombier goto loop11;
243*ce95e1b3SDavid du Colombier if(change)
244*ce95e1b3SDavid du Colombier goto loop1;
245*ce95e1b3SDavid du Colombier
246*ce95e1b3SDavid du Colombier
247*ce95e1b3SDavid du Colombier /*
248*ce95e1b3SDavid du Colombier * pass 4
249*ce95e1b3SDavid du Colombier * iterate propagating register/variable synchrony
250*ce95e1b3SDavid du Colombier * forward until graph is complete
251*ce95e1b3SDavid du Colombier */
252*ce95e1b3SDavid du Colombier loop2:
253*ce95e1b3SDavid du Colombier change = 0;
254*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link)
255*ce95e1b3SDavid du Colombier r->active = 0;
256*ce95e1b3SDavid du Colombier synch(firstr, zbits);
257*ce95e1b3SDavid du Colombier if(change)
258*ce95e1b3SDavid du Colombier goto loop2;
259*ce95e1b3SDavid du Colombier
260*ce95e1b3SDavid du Colombier addsplits();
261*ce95e1b3SDavid du Colombier
262*ce95e1b3SDavid du Colombier if(debug['R'] && debug['v']) {
263*ce95e1b3SDavid du Colombier print("\nprop structure:\n");
264*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link) {
265*ce95e1b3SDavid du Colombier print("%ld:%P", r->loop, r->prog);
266*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
267*ce95e1b3SDavid du Colombier bit.b[z] = r->set.b[z] |
268*ce95e1b3SDavid du Colombier r->refahead.b[z] | r->calahead.b[z] |
269*ce95e1b3SDavid du Colombier r->refbehind.b[z] | r->calbehind.b[z] |
270*ce95e1b3SDavid du Colombier r->use1.b[z] | r->use2.b[z];
271*ce95e1b3SDavid du Colombier if(bany(&bit)) {
272*ce95e1b3SDavid du Colombier print("\t");
273*ce95e1b3SDavid du Colombier if(bany(&r->use1))
274*ce95e1b3SDavid du Colombier print(" u1=%B", r->use1);
275*ce95e1b3SDavid du Colombier if(bany(&r->use2))
276*ce95e1b3SDavid du Colombier print(" u2=%B", r->use2);
277*ce95e1b3SDavid du Colombier if(bany(&r->set))
278*ce95e1b3SDavid du Colombier print(" st=%B", r->set);
279*ce95e1b3SDavid du Colombier if(bany(&r->refahead))
280*ce95e1b3SDavid du Colombier print(" ra=%B", r->refahead);
281*ce95e1b3SDavid du Colombier if(bany(&r->calahead))
282*ce95e1b3SDavid du Colombier print(" ca=%B", r->calahead);
283*ce95e1b3SDavid du Colombier if(bany(&r->refbehind))
284*ce95e1b3SDavid du Colombier print(" rb=%B", r->refbehind);
285*ce95e1b3SDavid du Colombier if(bany(&r->calbehind))
286*ce95e1b3SDavid du Colombier print(" cb=%B", r->calbehind);
287*ce95e1b3SDavid du Colombier if(bany(&r->regdiff))
288*ce95e1b3SDavid du Colombier print(" rd=%B", r->regdiff);
289*ce95e1b3SDavid du Colombier }
290*ce95e1b3SDavid du Colombier print("\n");
291*ce95e1b3SDavid du Colombier }
292*ce95e1b3SDavid du Colombier }
293*ce95e1b3SDavid du Colombier
294*ce95e1b3SDavid du Colombier /*
295*ce95e1b3SDavid du Colombier * pass 5
296*ce95e1b3SDavid du Colombier * isolate regions
297*ce95e1b3SDavid du Colombier * calculate costs (paint1)
298*ce95e1b3SDavid du Colombier */
299*ce95e1b3SDavid du Colombier r = firstr;
300*ce95e1b3SDavid du Colombier if(r) {
301*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
302*ce95e1b3SDavid du Colombier bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
303*ce95e1b3SDavid du Colombier ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
304*ce95e1b3SDavid du Colombier if(bany(&bit)) {
305*ce95e1b3SDavid du Colombier nearln = r->prog->lineno;
306*ce95e1b3SDavid du Colombier warn(Z, "used and not set: %B", bit);
307*ce95e1b3SDavid du Colombier if(debug['R'] && !debug['w'])
308*ce95e1b3SDavid du Colombier print("used and not set: %B\n", bit);
309*ce95e1b3SDavid du Colombier }
310*ce95e1b3SDavid du Colombier }
311*ce95e1b3SDavid du Colombier
312*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link)
313*ce95e1b3SDavid du Colombier r->act = zbits;
314*ce95e1b3SDavid du Colombier rgp = region;
315*ce95e1b3SDavid du Colombier nregion = 0;
316*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link) {
317*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
318*ce95e1b3SDavid du Colombier bit.b[z] = r->set.b[z] &
319*ce95e1b3SDavid du Colombier ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
320*ce95e1b3SDavid du Colombier if(bany(&bit)) {
321*ce95e1b3SDavid du Colombier nearln = r->prog->lineno;
322*ce95e1b3SDavid du Colombier warn(Z, "set and not used: %B", bit);
323*ce95e1b3SDavid du Colombier if(debug['R'])
324*ce95e1b3SDavid du Colombier print("set and not used: %B\n", bit);
325*ce95e1b3SDavid du Colombier excise(r);
326*ce95e1b3SDavid du Colombier }
327*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
328*ce95e1b3SDavid du Colombier bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
329*ce95e1b3SDavid du Colombier while(bany(&bit)) {
330*ce95e1b3SDavid du Colombier i = bnum(bit);
331*ce95e1b3SDavid du Colombier rgp->enter = r;
332*ce95e1b3SDavid du Colombier rgp->varno = i;
333*ce95e1b3SDavid du Colombier change = 0;
334*ce95e1b3SDavid du Colombier if(debug['R'] && debug['v'])
335*ce95e1b3SDavid du Colombier print("\n");
336*ce95e1b3SDavid du Colombier paint1(r, i);
337*ce95e1b3SDavid du Colombier bit.b[i/32] &= ~(1L<<(i%32));
338*ce95e1b3SDavid du Colombier if(change <= 0) {
339*ce95e1b3SDavid du Colombier if(debug['R'])
340*ce95e1b3SDavid du Colombier print("%L $%d: %B\n",
341*ce95e1b3SDavid du Colombier r->prog->lineno, change, blsh(i));
342*ce95e1b3SDavid du Colombier continue;
343*ce95e1b3SDavid du Colombier }
344*ce95e1b3SDavid du Colombier rgp->cost = change;
345*ce95e1b3SDavid du Colombier nregion++;
346*ce95e1b3SDavid du Colombier if(nregion >= NRGN) {
347*ce95e1b3SDavid du Colombier warn(Z, "too many regions");
348*ce95e1b3SDavid du Colombier goto brk;
349*ce95e1b3SDavid du Colombier }
350*ce95e1b3SDavid du Colombier rgp++;
351*ce95e1b3SDavid du Colombier }
352*ce95e1b3SDavid du Colombier }
353*ce95e1b3SDavid du Colombier brk:
354*ce95e1b3SDavid du Colombier qsort(region, nregion, sizeof(region[0]), rcmp);
355*ce95e1b3SDavid du Colombier
356*ce95e1b3SDavid du Colombier /*
357*ce95e1b3SDavid du Colombier * pass 6
358*ce95e1b3SDavid du Colombier * determine used registers (paint2)
359*ce95e1b3SDavid du Colombier * replace code (paint3)
360*ce95e1b3SDavid du Colombier */
361*ce95e1b3SDavid du Colombier rgp = region;
362*ce95e1b3SDavid du Colombier for(i=0; i<nregion; i++) {
363*ce95e1b3SDavid du Colombier bit = blsh(rgp->varno);
364*ce95e1b3SDavid du Colombier vreg = paint2(rgp->enter, rgp->varno);
365*ce95e1b3SDavid du Colombier vreg = allreg(vreg, rgp);
366*ce95e1b3SDavid du Colombier if(debug['R']) {
367*ce95e1b3SDavid du Colombier if(rgp->regno >= NREG)
368*ce95e1b3SDavid du Colombier print("%L $%d F%d: %B\n",
369*ce95e1b3SDavid du Colombier rgp->enter->prog->lineno,
370*ce95e1b3SDavid du Colombier rgp->cost,
371*ce95e1b3SDavid du Colombier rgp->regno-NREG,
372*ce95e1b3SDavid du Colombier bit);
373*ce95e1b3SDavid du Colombier else
374*ce95e1b3SDavid du Colombier print("%L $%d R%d: %B\n",
375*ce95e1b3SDavid du Colombier rgp->enter->prog->lineno,
376*ce95e1b3SDavid du Colombier rgp->cost,
377*ce95e1b3SDavid du Colombier rgp->regno,
378*ce95e1b3SDavid du Colombier bit);
379*ce95e1b3SDavid du Colombier }
380*ce95e1b3SDavid du Colombier if(rgp->regno != 0)
381*ce95e1b3SDavid du Colombier paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
382*ce95e1b3SDavid du Colombier rgp++;
383*ce95e1b3SDavid du Colombier }
384*ce95e1b3SDavid du Colombier /*
385*ce95e1b3SDavid du Colombier * pass 7
386*ce95e1b3SDavid du Colombier * peep-hole on basic block
387*ce95e1b3SDavid du Colombier */
388*ce95e1b3SDavid du Colombier if(!debug['R'] || debug['P'])
389*ce95e1b3SDavid du Colombier peep();
390*ce95e1b3SDavid du Colombier
391*ce95e1b3SDavid du Colombier /*
392*ce95e1b3SDavid du Colombier * pass 8
393*ce95e1b3SDavid du Colombier * recalculate pc
394*ce95e1b3SDavid du Colombier */
395*ce95e1b3SDavid du Colombier val = initpc;
396*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r1) {
397*ce95e1b3SDavid du Colombier r->pc = val;
398*ce95e1b3SDavid du Colombier p = r->prog;
399*ce95e1b3SDavid du Colombier p1 = P;
400*ce95e1b3SDavid du Colombier r1 = r->link;
401*ce95e1b3SDavid du Colombier if(r1 != R)
402*ce95e1b3SDavid du Colombier p1 = r1->prog;
403*ce95e1b3SDavid du Colombier for(; p != p1; p = p->link) {
404*ce95e1b3SDavid du Colombier switch(p->as) {
405*ce95e1b3SDavid du Colombier default:
406*ce95e1b3SDavid du Colombier val++;
407*ce95e1b3SDavid du Colombier break;
408*ce95e1b3SDavid du Colombier
409*ce95e1b3SDavid du Colombier case ANOP:
410*ce95e1b3SDavid du Colombier case ADATA:
411*ce95e1b3SDavid du Colombier case AGLOBL:
412*ce95e1b3SDavid du Colombier case ANAME:
413*ce95e1b3SDavid du Colombier case ASIGNAME:
414*ce95e1b3SDavid du Colombier break;
415*ce95e1b3SDavid du Colombier }
416*ce95e1b3SDavid du Colombier }
417*ce95e1b3SDavid du Colombier }
418*ce95e1b3SDavid du Colombier pc = val;
419*ce95e1b3SDavid du Colombier
420*ce95e1b3SDavid du Colombier /*
421*ce95e1b3SDavid du Colombier * fix up branches
422*ce95e1b3SDavid du Colombier */
423*ce95e1b3SDavid du Colombier if(debug['R'])
424*ce95e1b3SDavid du Colombier if(bany(&addrs))
425*ce95e1b3SDavid du Colombier print("addrs: %B\n", addrs);
426*ce95e1b3SDavid du Colombier
427*ce95e1b3SDavid du Colombier r1 = 0; /* set */
428*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link) {
429*ce95e1b3SDavid du Colombier p = r->prog;
430*ce95e1b3SDavid du Colombier if(p->to.type == D_BRANCH)
431*ce95e1b3SDavid du Colombier p->to.offset = r->s2->pc;
432*ce95e1b3SDavid du Colombier r1 = r;
433*ce95e1b3SDavid du Colombier }
434*ce95e1b3SDavid du Colombier
435*ce95e1b3SDavid du Colombier /*
436*ce95e1b3SDavid du Colombier * last pass
437*ce95e1b3SDavid du Colombier * fix unsigned stores (needed as type hint in pass 6)
438*ce95e1b3SDavid du Colombier * eliminate nops
439*ce95e1b3SDavid du Colombier * free aux structures
440*ce95e1b3SDavid du Colombier */
441*ce95e1b3SDavid du Colombier for(p = firstr->prog; p != P; p = p->link){
442*ce95e1b3SDavid du Colombier if(p->to.type == D_OREG){
443*ce95e1b3SDavid du Colombier switch(p->as){
444*ce95e1b3SDavid du Colombier case AMOVBU:
445*ce95e1b3SDavid du Colombier p->as = AMOVB;
446*ce95e1b3SDavid du Colombier break;
447*ce95e1b3SDavid du Colombier case AMOVHU:
448*ce95e1b3SDavid du Colombier p->as = AMOVH;
449*ce95e1b3SDavid du Colombier break;
450*ce95e1b3SDavid du Colombier }
451*ce95e1b3SDavid du Colombier }
452*ce95e1b3SDavid du Colombier while(p->link && p->link->as == ANOP)
453*ce95e1b3SDavid du Colombier p->link = p->link->link;
454*ce95e1b3SDavid du Colombier }
455*ce95e1b3SDavid du Colombier if(r1 != R) {
456*ce95e1b3SDavid du Colombier r1->link = freer;
457*ce95e1b3SDavid du Colombier freer = firstr;
458*ce95e1b3SDavid du Colombier }
459*ce95e1b3SDavid du Colombier }
460*ce95e1b3SDavid du Colombier
461*ce95e1b3SDavid du Colombier void
addsplits(void)462*ce95e1b3SDavid du Colombier addsplits(void)
463*ce95e1b3SDavid du Colombier {
464*ce95e1b3SDavid du Colombier Reg *r, *r1;
465*ce95e1b3SDavid du Colombier int z, i;
466*ce95e1b3SDavid du Colombier Bits bit;
467*ce95e1b3SDavid du Colombier
468*ce95e1b3SDavid du Colombier for(r = firstr; r != R; r = r->link) {
469*ce95e1b3SDavid du Colombier if(r->loop > 1)
470*ce95e1b3SDavid du Colombier continue;
471*ce95e1b3SDavid du Colombier if(r->prog->as == AJAL)
472*ce95e1b3SDavid du Colombier continue;
473*ce95e1b3SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link) {
474*ce95e1b3SDavid du Colombier if(r1->loop <= 1)
475*ce95e1b3SDavid du Colombier continue;
476*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
477*ce95e1b3SDavid du Colombier bit.b[z] = r1->calbehind.b[z] &
478*ce95e1b3SDavid du Colombier (r->refahead.b[z] | r->use1.b[z] | r->use2.b[z]) &
479*ce95e1b3SDavid du Colombier ~(r->calahead.b[z] & addrs.b[z]);
480*ce95e1b3SDavid du Colombier while(bany(&bit)) {
481*ce95e1b3SDavid du Colombier i = bnum(bit);
482*ce95e1b3SDavid du Colombier bit.b[i/32] &= ~(1L << (i%32));
483*ce95e1b3SDavid du Colombier }
484*ce95e1b3SDavid du Colombier }
485*ce95e1b3SDavid du Colombier }
486*ce95e1b3SDavid du Colombier }
487*ce95e1b3SDavid du Colombier
488*ce95e1b3SDavid du Colombier /*
489*ce95e1b3SDavid du Colombier * add mov b,rn
490*ce95e1b3SDavid du Colombier * just after r
491*ce95e1b3SDavid du Colombier */
492*ce95e1b3SDavid du Colombier void
addmove(Reg * r,int bn,int rn,int f)493*ce95e1b3SDavid du Colombier addmove(Reg *r, int bn, int rn, int f)
494*ce95e1b3SDavid du Colombier {
495*ce95e1b3SDavid du Colombier Prog *p, *p1;
496*ce95e1b3SDavid du Colombier Adr *a;
497*ce95e1b3SDavid du Colombier Var *v;
498*ce95e1b3SDavid du Colombier
499*ce95e1b3SDavid du Colombier p1 = alloc(sizeof(*p1));
500*ce95e1b3SDavid du Colombier *p1 = zprog;
501*ce95e1b3SDavid du Colombier p = r->prog;
502*ce95e1b3SDavid du Colombier
503*ce95e1b3SDavid du Colombier p1->link = p->link;
504*ce95e1b3SDavid du Colombier p->link = p1;
505*ce95e1b3SDavid du Colombier p1->lineno = p->lineno;
506*ce95e1b3SDavid du Colombier
507*ce95e1b3SDavid du Colombier v = var + bn;
508*ce95e1b3SDavid du Colombier
509*ce95e1b3SDavid du Colombier a = &p1->to;
510*ce95e1b3SDavid du Colombier a->sym = v->sym;
511*ce95e1b3SDavid du Colombier a->name = v->name;
512*ce95e1b3SDavid du Colombier a->offset = v->offset;
513*ce95e1b3SDavid du Colombier a->etype = v->etype;
514*ce95e1b3SDavid du Colombier a->type = D_OREG;
515*ce95e1b3SDavid du Colombier if(a->etype == TARRAY || a->sym == S)
516*ce95e1b3SDavid du Colombier a->type = D_CONST;
517*ce95e1b3SDavid du Colombier
518*ce95e1b3SDavid du Colombier p1->as = AMOVW;
519*ce95e1b3SDavid du Colombier if(v->etype == TCHAR || v->etype == TUCHAR)
520*ce95e1b3SDavid du Colombier p1->as = AMOVB;
521*ce95e1b3SDavid du Colombier if(v->etype == TSHORT || v->etype == TUSHORT)
522*ce95e1b3SDavid du Colombier p1->as = AMOVH;
523*ce95e1b3SDavid du Colombier if(v->etype == TFLOAT)
524*ce95e1b3SDavid du Colombier p1->as = AMOVF;
525*ce95e1b3SDavid du Colombier if(v->etype == TDOUBLE)
526*ce95e1b3SDavid du Colombier p1->as = AMOVD;
527*ce95e1b3SDavid du Colombier if(thechar == 'j')
528*ce95e1b3SDavid du Colombier if(v->etype == TVLONG || v->etype == TUVLONG || v->etype == TIND)
529*ce95e1b3SDavid du Colombier p1->as = AMOV;
530*ce95e1b3SDavid du Colombier
531*ce95e1b3SDavid du Colombier p1->from.type = D_REG;
532*ce95e1b3SDavid du Colombier p1->from.reg = rn;
533*ce95e1b3SDavid du Colombier if(rn >= NREG) {
534*ce95e1b3SDavid du Colombier p1->from.type = D_FREG;
535*ce95e1b3SDavid du Colombier p1->from.reg = rn-NREG;
536*ce95e1b3SDavid du Colombier }
537*ce95e1b3SDavid du Colombier if(!f) {
538*ce95e1b3SDavid du Colombier p1->from = *a;
539*ce95e1b3SDavid du Colombier *a = zprog.from;
540*ce95e1b3SDavid du Colombier a->type = D_REG;
541*ce95e1b3SDavid du Colombier a->reg = rn;
542*ce95e1b3SDavid du Colombier if(rn >= NREG) {
543*ce95e1b3SDavid du Colombier a->type = D_FREG;
544*ce95e1b3SDavid du Colombier a->reg = rn-NREG;
545*ce95e1b3SDavid du Colombier }
546*ce95e1b3SDavid du Colombier if(v->etype == TUCHAR)
547*ce95e1b3SDavid du Colombier p1->as = AMOVBU;
548*ce95e1b3SDavid du Colombier if(v->etype == TUSHORT)
549*ce95e1b3SDavid du Colombier p1->as = AMOVHU;
550*ce95e1b3SDavid du Colombier }
551*ce95e1b3SDavid du Colombier if(debug['R'])
552*ce95e1b3SDavid du Colombier print("%P\t.a%P\n", p, p1);
553*ce95e1b3SDavid du Colombier }
554*ce95e1b3SDavid du Colombier
555*ce95e1b3SDavid du Colombier Bits
mkvar(Adr * a,int docon)556*ce95e1b3SDavid du Colombier mkvar(Adr *a, int docon)
557*ce95e1b3SDavid du Colombier {
558*ce95e1b3SDavid du Colombier Var *v;
559*ce95e1b3SDavid du Colombier int i, t, n, et, z;
560*ce95e1b3SDavid du Colombier long o;
561*ce95e1b3SDavid du Colombier Bits bit;
562*ce95e1b3SDavid du Colombier Sym *s;
563*ce95e1b3SDavid du Colombier
564*ce95e1b3SDavid du Colombier t = a->type;
565*ce95e1b3SDavid du Colombier if(t == D_REG && a->reg != NREG)
566*ce95e1b3SDavid du Colombier regbits |= RtoB(a->reg);
567*ce95e1b3SDavid du Colombier if(t == D_FREG && a->reg != NREG)
568*ce95e1b3SDavid du Colombier regbits |= FtoB(a->reg);
569*ce95e1b3SDavid du Colombier s = a->sym;
570*ce95e1b3SDavid du Colombier o = a->offset;
571*ce95e1b3SDavid du Colombier et = a->etype;
572*ce95e1b3SDavid du Colombier if(s == S) {
573*ce95e1b3SDavid du Colombier if(t != D_CONST || !docon || a->reg != NREG)
574*ce95e1b3SDavid du Colombier goto none;
575*ce95e1b3SDavid du Colombier et = TLONG;
576*ce95e1b3SDavid du Colombier }
577*ce95e1b3SDavid du Colombier if(t == D_CONST) {
578*ce95e1b3SDavid du Colombier if(s == S && sval(o))
579*ce95e1b3SDavid du Colombier goto none;
580*ce95e1b3SDavid du Colombier }
581*ce95e1b3SDavid du Colombier
582*ce95e1b3SDavid du Colombier n = a->name;
583*ce95e1b3SDavid du Colombier v = var;
584*ce95e1b3SDavid du Colombier for(i=0; i<nvar; i++) {
585*ce95e1b3SDavid du Colombier if(s == v->sym)
586*ce95e1b3SDavid du Colombier if(n == v->name)
587*ce95e1b3SDavid du Colombier if(o == v->offset)
588*ce95e1b3SDavid du Colombier goto out;
589*ce95e1b3SDavid du Colombier v++;
590*ce95e1b3SDavid du Colombier }
591*ce95e1b3SDavid du Colombier if(s)
592*ce95e1b3SDavid du Colombier if(s->name[0] == '.')
593*ce95e1b3SDavid du Colombier goto none;
594*ce95e1b3SDavid du Colombier if(nvar >= NVAR) {
595*ce95e1b3SDavid du Colombier if(debug['w'] > 1 && s)
596*ce95e1b3SDavid du Colombier warn(Z, "variable not optimized: %s", s->name);
597*ce95e1b3SDavid du Colombier goto none;
598*ce95e1b3SDavid du Colombier }
599*ce95e1b3SDavid du Colombier i = nvar;
600*ce95e1b3SDavid du Colombier nvar++;
601*ce95e1b3SDavid du Colombier v = &var[i];
602*ce95e1b3SDavid du Colombier v->sym = s;
603*ce95e1b3SDavid du Colombier v->offset = o;
604*ce95e1b3SDavid du Colombier v->etype = et;
605*ce95e1b3SDavid du Colombier v->name = n;
606*ce95e1b3SDavid du Colombier if(debug['R'])
607*ce95e1b3SDavid du Colombier print("bit=%2d et=%2d %D\n", i, et, a);
608*ce95e1b3SDavid du Colombier out:
609*ce95e1b3SDavid du Colombier bit = blsh(i);
610*ce95e1b3SDavid du Colombier if(n == D_EXTERN || n == D_STATIC)
611*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
612*ce95e1b3SDavid du Colombier externs.b[z] |= bit.b[z];
613*ce95e1b3SDavid du Colombier if(n == D_PARAM)
614*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
615*ce95e1b3SDavid du Colombier params.b[z] |= bit.b[z];
616*ce95e1b3SDavid du Colombier if(v->etype != et || !typechlpfd[et]) /* funny punning */
617*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
618*ce95e1b3SDavid du Colombier addrs.b[z] |= bit.b[z];
619*ce95e1b3SDavid du Colombier if(t == D_CONST) {
620*ce95e1b3SDavid du Colombier if(s == S) {
621*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
622*ce95e1b3SDavid du Colombier consts.b[z] |= bit.b[z];
623*ce95e1b3SDavid du Colombier return bit;
624*ce95e1b3SDavid du Colombier }
625*ce95e1b3SDavid du Colombier if(et != TARRAY)
626*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
627*ce95e1b3SDavid du Colombier addrs.b[z] |= bit.b[z];
628*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
629*ce95e1b3SDavid du Colombier params.b[z] |= bit.b[z];
630*ce95e1b3SDavid du Colombier return bit;
631*ce95e1b3SDavid du Colombier }
632*ce95e1b3SDavid du Colombier if(t == D_OREG)
633*ce95e1b3SDavid du Colombier return bit;
634*ce95e1b3SDavid du Colombier
635*ce95e1b3SDavid du Colombier none:
636*ce95e1b3SDavid du Colombier return zbits;
637*ce95e1b3SDavid du Colombier }
638*ce95e1b3SDavid du Colombier
639*ce95e1b3SDavid du Colombier void
prop(Reg * r,Bits ref,Bits cal)640*ce95e1b3SDavid du Colombier prop(Reg *r, Bits ref, Bits cal)
641*ce95e1b3SDavid du Colombier {
642*ce95e1b3SDavid du Colombier Reg *r1, *r2;
643*ce95e1b3SDavid du Colombier int z;
644*ce95e1b3SDavid du Colombier
645*ce95e1b3SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->p1) {
646*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
647*ce95e1b3SDavid du Colombier ref.b[z] |= r1->refahead.b[z];
648*ce95e1b3SDavid du Colombier if(ref.b[z] != r1->refahead.b[z]) {
649*ce95e1b3SDavid du Colombier r1->refahead.b[z] = ref.b[z];
650*ce95e1b3SDavid du Colombier change++;
651*ce95e1b3SDavid du Colombier }
652*ce95e1b3SDavid du Colombier cal.b[z] |= r1->calahead.b[z];
653*ce95e1b3SDavid du Colombier if(cal.b[z] != r1->calahead.b[z]) {
654*ce95e1b3SDavid du Colombier r1->calahead.b[z] = cal.b[z];
655*ce95e1b3SDavid du Colombier change++;
656*ce95e1b3SDavid du Colombier }
657*ce95e1b3SDavid du Colombier }
658*ce95e1b3SDavid du Colombier switch(r1->prog->as) {
659*ce95e1b3SDavid du Colombier case AJAL:
660*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
661*ce95e1b3SDavid du Colombier cal.b[z] |= ref.b[z] | externs.b[z];
662*ce95e1b3SDavid du Colombier ref.b[z] = 0;
663*ce95e1b3SDavid du Colombier }
664*ce95e1b3SDavid du Colombier break;
665*ce95e1b3SDavid du Colombier
666*ce95e1b3SDavid du Colombier case ATEXT:
667*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
668*ce95e1b3SDavid du Colombier cal.b[z] = 0;
669*ce95e1b3SDavid du Colombier ref.b[z] = 0;
670*ce95e1b3SDavid du Colombier }
671*ce95e1b3SDavid du Colombier break;
672*ce95e1b3SDavid du Colombier
673*ce95e1b3SDavid du Colombier case ARET:
674*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
675*ce95e1b3SDavid du Colombier cal.b[z] = externs.b[z];
676*ce95e1b3SDavid du Colombier ref.b[z] = 0;
677*ce95e1b3SDavid du Colombier }
678*ce95e1b3SDavid du Colombier }
679*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
680*ce95e1b3SDavid du Colombier ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
681*ce95e1b3SDavid du Colombier r1->use1.b[z] | r1->use2.b[z];
682*ce95e1b3SDavid du Colombier cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
683*ce95e1b3SDavid du Colombier r1->refbehind.b[z] = ref.b[z];
684*ce95e1b3SDavid du Colombier r1->calbehind.b[z] = cal.b[z];
685*ce95e1b3SDavid du Colombier }
686*ce95e1b3SDavid du Colombier if(r1->active)
687*ce95e1b3SDavid du Colombier break;
688*ce95e1b3SDavid du Colombier r1->active = 1;
689*ce95e1b3SDavid du Colombier }
690*ce95e1b3SDavid du Colombier for(; r != r1; r = r->p1)
691*ce95e1b3SDavid du Colombier for(r2 = r->p2; r2 != R; r2 = r2->p2link)
692*ce95e1b3SDavid du Colombier prop(r2, r->refbehind, r->calbehind);
693*ce95e1b3SDavid du Colombier }
694*ce95e1b3SDavid du Colombier
695*ce95e1b3SDavid du Colombier /*
696*ce95e1b3SDavid du Colombier * find looping structure
697*ce95e1b3SDavid du Colombier *
698*ce95e1b3SDavid du Colombier * 1) find reverse postordering
699*ce95e1b3SDavid du Colombier * 2) find approximate dominators,
700*ce95e1b3SDavid du Colombier * the actual dominators if the flow graph is reducible
701*ce95e1b3SDavid du Colombier * otherwise, dominators plus some other non-dominators.
702*ce95e1b3SDavid du Colombier * See Matthew S. Hecht and Jeffrey D. Ullman,
703*ce95e1b3SDavid du Colombier * "Analysis of a Simple Algorithm for Global Data Flow Problems",
704*ce95e1b3SDavid du Colombier * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
705*ce95e1b3SDavid du Colombier * Oct. 1-3, 1973, pp. 207-217.
706*ce95e1b3SDavid du Colombier * 3) find all nodes with a predecessor dominated by the current node.
707*ce95e1b3SDavid du Colombier * such a node is a loop head.
708*ce95e1b3SDavid du Colombier * recursively, all preds with a greater rpo number are in the loop
709*ce95e1b3SDavid du Colombier */
710*ce95e1b3SDavid du Colombier long
postorder(Reg * r,Reg ** rpo2r,long n)711*ce95e1b3SDavid du Colombier postorder(Reg *r, Reg **rpo2r, long n)
712*ce95e1b3SDavid du Colombier {
713*ce95e1b3SDavid du Colombier Reg *r1;
714*ce95e1b3SDavid du Colombier
715*ce95e1b3SDavid du Colombier r->rpo = 1;
716*ce95e1b3SDavid du Colombier r1 = r->s1;
717*ce95e1b3SDavid du Colombier if(r1 && !r1->rpo)
718*ce95e1b3SDavid du Colombier n = postorder(r1, rpo2r, n);
719*ce95e1b3SDavid du Colombier r1 = r->s2;
720*ce95e1b3SDavid du Colombier if(r1 && !r1->rpo)
721*ce95e1b3SDavid du Colombier n = postorder(r1, rpo2r, n);
722*ce95e1b3SDavid du Colombier rpo2r[n] = r;
723*ce95e1b3SDavid du Colombier n++;
724*ce95e1b3SDavid du Colombier return n;
725*ce95e1b3SDavid du Colombier }
726*ce95e1b3SDavid du Colombier
727*ce95e1b3SDavid du Colombier long
rpolca(long * idom,long rpo1,long rpo2)728*ce95e1b3SDavid du Colombier rpolca(long *idom, long rpo1, long rpo2)
729*ce95e1b3SDavid du Colombier {
730*ce95e1b3SDavid du Colombier long t;
731*ce95e1b3SDavid du Colombier
732*ce95e1b3SDavid du Colombier if(rpo1 == -1)
733*ce95e1b3SDavid du Colombier return rpo2;
734*ce95e1b3SDavid du Colombier while(rpo1 != rpo2){
735*ce95e1b3SDavid du Colombier if(rpo1 > rpo2){
736*ce95e1b3SDavid du Colombier t = rpo2;
737*ce95e1b3SDavid du Colombier rpo2 = rpo1;
738*ce95e1b3SDavid du Colombier rpo1 = t;
739*ce95e1b3SDavid du Colombier }
740*ce95e1b3SDavid du Colombier while(rpo1 < rpo2){
741*ce95e1b3SDavid du Colombier t = idom[rpo2];
742*ce95e1b3SDavid du Colombier if(t >= rpo2)
743*ce95e1b3SDavid du Colombier fatal(Z, "bad idom");
744*ce95e1b3SDavid du Colombier rpo2 = t;
745*ce95e1b3SDavid du Colombier }
746*ce95e1b3SDavid du Colombier }
747*ce95e1b3SDavid du Colombier return rpo1;
748*ce95e1b3SDavid du Colombier }
749*ce95e1b3SDavid du Colombier
750*ce95e1b3SDavid du Colombier int
doms(long * idom,long r,long s)751*ce95e1b3SDavid du Colombier doms(long *idom, long r, long s)
752*ce95e1b3SDavid du Colombier {
753*ce95e1b3SDavid du Colombier while(s > r)
754*ce95e1b3SDavid du Colombier s = idom[s];
755*ce95e1b3SDavid du Colombier return s == r;
756*ce95e1b3SDavid du Colombier }
757*ce95e1b3SDavid du Colombier
758*ce95e1b3SDavid du Colombier int
loophead(long * idom,Reg * r)759*ce95e1b3SDavid du Colombier loophead(long *idom, Reg *r)
760*ce95e1b3SDavid du Colombier {
761*ce95e1b3SDavid du Colombier long src;
762*ce95e1b3SDavid du Colombier
763*ce95e1b3SDavid du Colombier src = r->rpo;
764*ce95e1b3SDavid du Colombier if(r->p1 != R && doms(idom, src, r->p1->rpo))
765*ce95e1b3SDavid du Colombier return 1;
766*ce95e1b3SDavid du Colombier for(r = r->p2; r != R; r = r->p2link)
767*ce95e1b3SDavid du Colombier if(doms(idom, src, r->rpo))
768*ce95e1b3SDavid du Colombier return 1;
769*ce95e1b3SDavid du Colombier return 0;
770*ce95e1b3SDavid du Colombier }
771*ce95e1b3SDavid du Colombier
772*ce95e1b3SDavid du Colombier void
loopmark(Reg ** rpo2r,long head,Reg * r)773*ce95e1b3SDavid du Colombier loopmark(Reg **rpo2r, long head, Reg *r)
774*ce95e1b3SDavid du Colombier {
775*ce95e1b3SDavid du Colombier if(r->rpo < head || r->active == head)
776*ce95e1b3SDavid du Colombier return;
777*ce95e1b3SDavid du Colombier r->active = head;
778*ce95e1b3SDavid du Colombier r->loop += LOOP;
779*ce95e1b3SDavid du Colombier if(r->p1 != R)
780*ce95e1b3SDavid du Colombier loopmark(rpo2r, head, r->p1);
781*ce95e1b3SDavid du Colombier for(r = r->p2; r != R; r = r->p2link)
782*ce95e1b3SDavid du Colombier loopmark(rpo2r, head, r);
783*ce95e1b3SDavid du Colombier }
784*ce95e1b3SDavid du Colombier
785*ce95e1b3SDavid du Colombier void
loopit(Reg * r,long nr)786*ce95e1b3SDavid du Colombier loopit(Reg *r, long nr)
787*ce95e1b3SDavid du Colombier {
788*ce95e1b3SDavid du Colombier Reg *r1;
789*ce95e1b3SDavid du Colombier long i, d, me;
790*ce95e1b3SDavid du Colombier
791*ce95e1b3SDavid du Colombier if(nr > maxnr) {
792*ce95e1b3SDavid du Colombier rpo2r = alloc(nr * sizeof(Reg*));
793*ce95e1b3SDavid du Colombier idom = alloc(nr * sizeof(long));
794*ce95e1b3SDavid du Colombier maxnr = nr;
795*ce95e1b3SDavid du Colombier }
796*ce95e1b3SDavid du Colombier
797*ce95e1b3SDavid du Colombier d = postorder(r, rpo2r, 0);
798*ce95e1b3SDavid du Colombier if(d > nr)
799*ce95e1b3SDavid du Colombier fatal(Z, "too many reg nodes");
800*ce95e1b3SDavid du Colombier nr = d;
801*ce95e1b3SDavid du Colombier for(i = 0; i < nr / 2; i++){
802*ce95e1b3SDavid du Colombier r1 = rpo2r[i];
803*ce95e1b3SDavid du Colombier rpo2r[i] = rpo2r[nr - 1 - i];
804*ce95e1b3SDavid du Colombier rpo2r[nr - 1 - i] = r1;
805*ce95e1b3SDavid du Colombier }
806*ce95e1b3SDavid du Colombier for(i = 0; i < nr; i++)
807*ce95e1b3SDavid du Colombier rpo2r[i]->rpo = i;
808*ce95e1b3SDavid du Colombier
809*ce95e1b3SDavid du Colombier idom[0] = 0;
810*ce95e1b3SDavid du Colombier for(i = 0; i < nr; i++){
811*ce95e1b3SDavid du Colombier r1 = rpo2r[i];
812*ce95e1b3SDavid du Colombier me = r1->rpo;
813*ce95e1b3SDavid du Colombier d = -1;
814*ce95e1b3SDavid du Colombier if(r1->p1 != R && r1->p1->rpo < me)
815*ce95e1b3SDavid du Colombier d = r1->p1->rpo;
816*ce95e1b3SDavid du Colombier for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
817*ce95e1b3SDavid du Colombier if(r1->rpo < me)
818*ce95e1b3SDavid du Colombier d = rpolca(idom, d, r1->rpo);
819*ce95e1b3SDavid du Colombier idom[i] = d;
820*ce95e1b3SDavid du Colombier }
821*ce95e1b3SDavid du Colombier
822*ce95e1b3SDavid du Colombier for(i = 0; i < nr; i++){
823*ce95e1b3SDavid du Colombier r1 = rpo2r[i];
824*ce95e1b3SDavid du Colombier r1->loop++;
825*ce95e1b3SDavid du Colombier if(r1->p2 != R && loophead(idom, r1))
826*ce95e1b3SDavid du Colombier loopmark(rpo2r, i, r1);
827*ce95e1b3SDavid du Colombier }
828*ce95e1b3SDavid du Colombier }
829*ce95e1b3SDavid du Colombier
830*ce95e1b3SDavid du Colombier void
synch(Reg * r,Bits dif)831*ce95e1b3SDavid du Colombier synch(Reg *r, Bits dif)
832*ce95e1b3SDavid du Colombier {
833*ce95e1b3SDavid du Colombier Reg *r1;
834*ce95e1b3SDavid du Colombier int z;
835*ce95e1b3SDavid du Colombier
836*ce95e1b3SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->s1) {
837*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++) {
838*ce95e1b3SDavid du Colombier dif.b[z] = (dif.b[z] &
839*ce95e1b3SDavid du Colombier ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
840*ce95e1b3SDavid du Colombier r1->set.b[z] | r1->regdiff.b[z];
841*ce95e1b3SDavid du Colombier if(dif.b[z] != r1->regdiff.b[z]) {
842*ce95e1b3SDavid du Colombier r1->regdiff.b[z] = dif.b[z];
843*ce95e1b3SDavid du Colombier change++;
844*ce95e1b3SDavid du Colombier }
845*ce95e1b3SDavid du Colombier }
846*ce95e1b3SDavid du Colombier if(r1->active)
847*ce95e1b3SDavid du Colombier break;
848*ce95e1b3SDavid du Colombier r1->active = 1;
849*ce95e1b3SDavid du Colombier for(z=0; z<BITS; z++)
850*ce95e1b3SDavid du Colombier dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
851*ce95e1b3SDavid du Colombier if(r1->s2 != R)
852*ce95e1b3SDavid du Colombier synch(r1->s2, dif);
853*ce95e1b3SDavid du Colombier }
854*ce95e1b3SDavid du Colombier }
855*ce95e1b3SDavid du Colombier
856*ce95e1b3SDavid du Colombier ulong
allreg(ulong b,Rgn * r)857*ce95e1b3SDavid du Colombier allreg(ulong b, Rgn *r)
858*ce95e1b3SDavid du Colombier {
859*ce95e1b3SDavid du Colombier Var *v;
860*ce95e1b3SDavid du Colombier int i;
861*ce95e1b3SDavid du Colombier
862*ce95e1b3SDavid du Colombier v = var + r->varno;
863*ce95e1b3SDavid du Colombier r->regno = 0;
864*ce95e1b3SDavid du Colombier switch(v->etype) {
865*ce95e1b3SDavid du Colombier
866*ce95e1b3SDavid du Colombier default:
867*ce95e1b3SDavid du Colombier diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
868*ce95e1b3SDavid du Colombier break;
869*ce95e1b3SDavid du Colombier
870*ce95e1b3SDavid du Colombier case TCHAR:
871*ce95e1b3SDavid du Colombier case TUCHAR:
872*ce95e1b3SDavid du Colombier case TSHORT:
873*ce95e1b3SDavid du Colombier case TUSHORT:
874*ce95e1b3SDavid du Colombier case TINT:
875*ce95e1b3SDavid du Colombier case TUINT:
876*ce95e1b3SDavid du Colombier case TLONG:
877*ce95e1b3SDavid du Colombier case TULONG:
878*ce95e1b3SDavid du Colombier case TIND:
879*ce95e1b3SDavid du Colombier case TARRAY:
880*ce95e1b3SDavid du Colombier i = BtoR(~b);
881*ce95e1b3SDavid du Colombier if(i && r->cost >= 0) {
882*ce95e1b3SDavid du Colombier r->regno = i;
883*ce95e1b3SDavid du Colombier return RtoB(i);
884*ce95e1b3SDavid du Colombier }
885*ce95e1b3SDavid du Colombier break;
886*ce95e1b3SDavid du Colombier
887*ce95e1b3SDavid du Colombier case TDOUBLE:
888*ce95e1b3SDavid du Colombier case TFLOAT:
889*ce95e1b3SDavid du Colombier i = BtoF(~b);
890*ce95e1b3SDavid du Colombier if(i && r->cost >= 0) {
891*ce95e1b3SDavid du Colombier r->regno = i+NREG;
892*ce95e1b3SDavid du Colombier return FtoB(i);
893*ce95e1b3SDavid du Colombier }
894*ce95e1b3SDavid du Colombier break;
895*ce95e1b3SDavid du Colombier }
896*ce95e1b3SDavid du Colombier return 0;
897*ce95e1b3SDavid du Colombier }
898*ce95e1b3SDavid du Colombier
899*ce95e1b3SDavid du Colombier void
paint1(Reg * r,int bn)900*ce95e1b3SDavid du Colombier paint1(Reg *r, int bn)
901*ce95e1b3SDavid du Colombier {
902*ce95e1b3SDavid du Colombier Reg *r1;
903*ce95e1b3SDavid du Colombier Prog *p;
904*ce95e1b3SDavid du Colombier int z;
905*ce95e1b3SDavid du Colombier ulong bb;
906*ce95e1b3SDavid du Colombier
907*ce95e1b3SDavid du Colombier z = bn/32;
908*ce95e1b3SDavid du Colombier bb = 1L<<(bn%32);
909*ce95e1b3SDavid du Colombier if(r->act.b[z] & bb)
910*ce95e1b3SDavid du Colombier return;
911*ce95e1b3SDavid du Colombier for(;;) {
912*ce95e1b3SDavid du Colombier if(!(r->refbehind.b[z] & bb))
913*ce95e1b3SDavid du Colombier break;
914*ce95e1b3SDavid du Colombier r1 = r->p1;
915*ce95e1b3SDavid du Colombier if(r1 == R)
916*ce95e1b3SDavid du Colombier break;
917*ce95e1b3SDavid du Colombier if(!(r1->refahead.b[z] & bb))
918*ce95e1b3SDavid du Colombier break;
919*ce95e1b3SDavid du Colombier if(r1->act.b[z] & bb)
920*ce95e1b3SDavid du Colombier break;
921*ce95e1b3SDavid du Colombier r = r1;
922*ce95e1b3SDavid du Colombier }
923*ce95e1b3SDavid du Colombier
924*ce95e1b3SDavid du Colombier if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) {
925*ce95e1b3SDavid du Colombier change -= CLOAD * r->loop;
926*ce95e1b3SDavid du Colombier if(debug['R'] && debug['v'])
927*ce95e1b3SDavid du Colombier print("%ld%P\tld %B $%d\n", r->loop,
928*ce95e1b3SDavid du Colombier r->prog, blsh(bn), change);
929*ce95e1b3SDavid du Colombier }
930*ce95e1b3SDavid du Colombier for(;;) {
931*ce95e1b3SDavid du Colombier r->act.b[z] |= bb;
932*ce95e1b3SDavid du Colombier p = r->prog;
933*ce95e1b3SDavid du Colombier
934*ce95e1b3SDavid du Colombier if(r->use1.b[z] & bb) {
935*ce95e1b3SDavid du Colombier change += CREF * r->loop;
936*ce95e1b3SDavid du Colombier if(debug['R'] && debug['v'])
937*ce95e1b3SDavid du Colombier print("%ld%P\tu1 %B $%d\n", r->loop,
938*ce95e1b3SDavid du Colombier p, blsh(bn), change);
939*ce95e1b3SDavid du Colombier }
940*ce95e1b3SDavid du Colombier
941*ce95e1b3SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) {
942*ce95e1b3SDavid du Colombier change += CREF * r->loop;
943*ce95e1b3SDavid du Colombier if(debug['R'] && debug['v'])
944*ce95e1b3SDavid du Colombier print("%ld%P\tu2 %B $%d\n", r->loop,
945*ce95e1b3SDavid du Colombier p, blsh(bn), change);
946*ce95e1b3SDavid du Colombier }
947*ce95e1b3SDavid du Colombier
948*ce95e1b3SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb) {
949*ce95e1b3SDavid du Colombier change -= CLOAD * r->loop;
950*ce95e1b3SDavid du Colombier if(debug['R'] && debug['v'])
951*ce95e1b3SDavid du Colombier print("%ld%P\tst %B $%d\n", r->loop,
952*ce95e1b3SDavid du Colombier p, blsh(bn), change);
953*ce95e1b3SDavid du Colombier }
954*ce95e1b3SDavid du Colombier
955*ce95e1b3SDavid du Colombier if(r->refbehind.b[z] & bb)
956*ce95e1b3SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
957*ce95e1b3SDavid du Colombier if(r1->refahead.b[z] & bb)
958*ce95e1b3SDavid du Colombier paint1(r1, bn);
959*ce95e1b3SDavid du Colombier
960*ce95e1b3SDavid du Colombier if(!(r->refahead.b[z] & bb))
961*ce95e1b3SDavid du Colombier break;
962*ce95e1b3SDavid du Colombier r1 = r->s2;
963*ce95e1b3SDavid du Colombier if(r1 != R)
964*ce95e1b3SDavid du Colombier if(r1->refbehind.b[z] & bb)
965*ce95e1b3SDavid du Colombier paint1(r1, bn);
966*ce95e1b3SDavid du Colombier r = r->s1;
967*ce95e1b3SDavid du Colombier if(r == R)
968*ce95e1b3SDavid du Colombier break;
969*ce95e1b3SDavid du Colombier if(r->act.b[z] & bb)
970*ce95e1b3SDavid du Colombier break;
971*ce95e1b3SDavid du Colombier if(!(r->refbehind.b[z] & bb))
972*ce95e1b3SDavid du Colombier break;
973*ce95e1b3SDavid du Colombier }
974*ce95e1b3SDavid du Colombier }
975*ce95e1b3SDavid du Colombier
976*ce95e1b3SDavid du Colombier ulong
paint2(Reg * r,int bn)977*ce95e1b3SDavid du Colombier paint2(Reg *r, int bn)
978*ce95e1b3SDavid du Colombier {
979*ce95e1b3SDavid du Colombier Reg *r1;
980*ce95e1b3SDavid du Colombier int z;
981*ce95e1b3SDavid du Colombier ulong bb, vreg;
982*ce95e1b3SDavid du Colombier
983*ce95e1b3SDavid du Colombier z = bn/32;
984*ce95e1b3SDavid du Colombier bb = 1L << (bn%32);
985*ce95e1b3SDavid du Colombier vreg = regbits;
986*ce95e1b3SDavid du Colombier if(!(r->act.b[z] & bb))
987*ce95e1b3SDavid du Colombier return vreg;
988*ce95e1b3SDavid du Colombier for(;;) {
989*ce95e1b3SDavid du Colombier if(!(r->refbehind.b[z] & bb))
990*ce95e1b3SDavid du Colombier break;
991*ce95e1b3SDavid du Colombier r1 = r->p1;
992*ce95e1b3SDavid du Colombier if(r1 == R)
993*ce95e1b3SDavid du Colombier break;
994*ce95e1b3SDavid du Colombier if(!(r1->refahead.b[z] & bb))
995*ce95e1b3SDavid du Colombier break;
996*ce95e1b3SDavid du Colombier if(!(r1->act.b[z] & bb))
997*ce95e1b3SDavid du Colombier break;
998*ce95e1b3SDavid du Colombier r = r1;
999*ce95e1b3SDavid du Colombier }
1000*ce95e1b3SDavid du Colombier for(;;) {
1001*ce95e1b3SDavid du Colombier r->act.b[z] &= ~bb;
1002*ce95e1b3SDavid du Colombier
1003*ce95e1b3SDavid du Colombier vreg |= r->regu;
1004*ce95e1b3SDavid du Colombier
1005*ce95e1b3SDavid du Colombier if(r->refbehind.b[z] & bb)
1006*ce95e1b3SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1007*ce95e1b3SDavid du Colombier if(r1->refahead.b[z] & bb)
1008*ce95e1b3SDavid du Colombier vreg |= paint2(r1, bn);
1009*ce95e1b3SDavid du Colombier
1010*ce95e1b3SDavid du Colombier if(!(r->refahead.b[z] & bb))
1011*ce95e1b3SDavid du Colombier break;
1012*ce95e1b3SDavid du Colombier r1 = r->s2;
1013*ce95e1b3SDavid du Colombier if(r1 != R)
1014*ce95e1b3SDavid du Colombier if(r1->refbehind.b[z] & bb)
1015*ce95e1b3SDavid du Colombier vreg |= paint2(r1, bn);
1016*ce95e1b3SDavid du Colombier r = r->s1;
1017*ce95e1b3SDavid du Colombier if(r == R)
1018*ce95e1b3SDavid du Colombier break;
1019*ce95e1b3SDavid du Colombier if(!(r->act.b[z] & bb))
1020*ce95e1b3SDavid du Colombier break;
1021*ce95e1b3SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1022*ce95e1b3SDavid du Colombier break;
1023*ce95e1b3SDavid du Colombier }
1024*ce95e1b3SDavid du Colombier return vreg;
1025*ce95e1b3SDavid du Colombier }
1026*ce95e1b3SDavid du Colombier
1027*ce95e1b3SDavid du Colombier void
paint3(Reg * r,int bn,long rb,int rn)1028*ce95e1b3SDavid du Colombier paint3(Reg *r, int bn, long rb, int rn)
1029*ce95e1b3SDavid du Colombier {
1030*ce95e1b3SDavid du Colombier Reg *r1;
1031*ce95e1b3SDavid du Colombier Prog *p;
1032*ce95e1b3SDavid du Colombier int z;
1033*ce95e1b3SDavid du Colombier ulong bb;
1034*ce95e1b3SDavid du Colombier
1035*ce95e1b3SDavid du Colombier z = bn/32;
1036*ce95e1b3SDavid du Colombier bb = 1L << (bn%32);
1037*ce95e1b3SDavid du Colombier if(r->act.b[z] & bb)
1038*ce95e1b3SDavid du Colombier return;
1039*ce95e1b3SDavid du Colombier for(;;) {
1040*ce95e1b3SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1041*ce95e1b3SDavid du Colombier break;
1042*ce95e1b3SDavid du Colombier r1 = r->p1;
1043*ce95e1b3SDavid du Colombier if(r1 == R)
1044*ce95e1b3SDavid du Colombier break;
1045*ce95e1b3SDavid du Colombier if(!(r1->refahead.b[z] & bb))
1046*ce95e1b3SDavid du Colombier break;
1047*ce95e1b3SDavid du Colombier if(r1->act.b[z] & bb)
1048*ce95e1b3SDavid du Colombier break;
1049*ce95e1b3SDavid du Colombier r = r1;
1050*ce95e1b3SDavid du Colombier }
1051*ce95e1b3SDavid du Colombier
1052*ce95e1b3SDavid du Colombier if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
1053*ce95e1b3SDavid du Colombier addmove(r, bn, rn, 0);
1054*ce95e1b3SDavid du Colombier for(;;) {
1055*ce95e1b3SDavid du Colombier r->act.b[z] |= bb;
1056*ce95e1b3SDavid du Colombier p = r->prog;
1057*ce95e1b3SDavid du Colombier
1058*ce95e1b3SDavid du Colombier if(r->use1.b[z] & bb) {
1059*ce95e1b3SDavid du Colombier if(debug['R'])
1060*ce95e1b3SDavid du Colombier print("%P", p);
1061*ce95e1b3SDavid du Colombier addreg(&p->from, rn);
1062*ce95e1b3SDavid du Colombier switch(p->as){
1063*ce95e1b3SDavid du Colombier case AMOVB:
1064*ce95e1b3SDavid du Colombier case AMOVBU:
1065*ce95e1b3SDavid du Colombier case AMOVH:
1066*ce95e1b3SDavid du Colombier case AMOVHU:
1067*ce95e1b3SDavid du Colombier case AMOVW:
1068*ce95e1b3SDavid du Colombier case AMOVWU:
1069*ce95e1b3SDavid du Colombier p->as = AMOV;
1070*ce95e1b3SDavid du Colombier }
1071*ce95e1b3SDavid du Colombier if(debug['R'])
1072*ce95e1b3SDavid du Colombier print("\t.c%P\n", p);
1073*ce95e1b3SDavid du Colombier }
1074*ce95e1b3SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) {
1075*ce95e1b3SDavid du Colombier if(debug['R'])
1076*ce95e1b3SDavid du Colombier print("%P", p);
1077*ce95e1b3SDavid du Colombier addreg(&p->to, rn);
1078*ce95e1b3SDavid du Colombier if(debug['R'])
1079*ce95e1b3SDavid du Colombier print("\t.c%P\n", p);
1080*ce95e1b3SDavid du Colombier }
1081*ce95e1b3SDavid du Colombier
1082*ce95e1b3SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb)
1083*ce95e1b3SDavid du Colombier addmove(r, bn, rn, 1);
1084*ce95e1b3SDavid du Colombier r->regu |= rb;
1085*ce95e1b3SDavid du Colombier
1086*ce95e1b3SDavid du Colombier if(r->refbehind.b[z] & bb)
1087*ce95e1b3SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1088*ce95e1b3SDavid du Colombier if(r1->refahead.b[z] & bb)
1089*ce95e1b3SDavid du Colombier paint3(r1, bn, rb, rn);
1090*ce95e1b3SDavid du Colombier
1091*ce95e1b3SDavid du Colombier if(!(r->refahead.b[z] & bb))
1092*ce95e1b3SDavid du Colombier break;
1093*ce95e1b3SDavid du Colombier r1 = r->s2;
1094*ce95e1b3SDavid du Colombier if(r1 != R)
1095*ce95e1b3SDavid du Colombier if(r1->refbehind.b[z] & bb)
1096*ce95e1b3SDavid du Colombier paint3(r1, bn, rb, rn);
1097*ce95e1b3SDavid du Colombier r = r->s1;
1098*ce95e1b3SDavid du Colombier if(r == R)
1099*ce95e1b3SDavid du Colombier break;
1100*ce95e1b3SDavid du Colombier if(r->act.b[z] & bb)
1101*ce95e1b3SDavid du Colombier break;
1102*ce95e1b3SDavid du Colombier if(!(r->refbehind.b[z] & bb))
1103*ce95e1b3SDavid du Colombier break;
1104*ce95e1b3SDavid du Colombier }
1105*ce95e1b3SDavid du Colombier }
1106*ce95e1b3SDavid du Colombier
1107*ce95e1b3SDavid du Colombier void
addreg(Adr * a,int rn)1108*ce95e1b3SDavid du Colombier addreg(Adr *a, int rn)
1109*ce95e1b3SDavid du Colombier {
1110*ce95e1b3SDavid du Colombier
1111*ce95e1b3SDavid du Colombier a->sym = 0;
1112*ce95e1b3SDavid du Colombier a->name = D_NONE;
1113*ce95e1b3SDavid du Colombier a->type = D_REG;
1114*ce95e1b3SDavid du Colombier a->reg = rn;
1115*ce95e1b3SDavid du Colombier if(rn >= NREG) {
1116*ce95e1b3SDavid du Colombier a->type = D_FREG;
1117*ce95e1b3SDavid du Colombier a->reg = rn-NREG;
1118*ce95e1b3SDavid du Colombier }
1119*ce95e1b3SDavid du Colombier }
1120*ce95e1b3SDavid du Colombier
1121*ce95e1b3SDavid du Colombier /*
1122*ce95e1b3SDavid du Colombier * bit reg
1123*ce95e1b3SDavid du Colombier * 0 R9
1124*ce95e1b3SDavid du Colombier * 1 R10
1125*ce95e1b3SDavid du Colombier * ... ...
1126*ce95e1b3SDavid du Colombier * 6 R15
1127*ce95e1b3SDavid du Colombier */
1128*ce95e1b3SDavid du Colombier long
RtoB(int r)1129*ce95e1b3SDavid du Colombier RtoB(int r)
1130*ce95e1b3SDavid du Colombier {
1131*ce95e1b3SDavid du Colombier
1132*ce95e1b3SDavid du Colombier if(r < 9 || r > 15)
1133*ce95e1b3SDavid du Colombier return 0;
1134*ce95e1b3SDavid du Colombier return 1L << (r-9);
1135*ce95e1b3SDavid du Colombier }
1136*ce95e1b3SDavid du Colombier
1137*ce95e1b3SDavid du Colombier int
BtoR(long b)1138*ce95e1b3SDavid du Colombier BtoR(long b)
1139*ce95e1b3SDavid du Colombier {
1140*ce95e1b3SDavid du Colombier
1141*ce95e1b3SDavid du Colombier b &= 0x007fL;
1142*ce95e1b3SDavid du Colombier if(b == 0)
1143*ce95e1b3SDavid du Colombier return 0;
1144*ce95e1b3SDavid du Colombier return bitno(b) + 9;
1145*ce95e1b3SDavid du Colombier }
1146*ce95e1b3SDavid du Colombier
1147*ce95e1b3SDavid du Colombier /*
1148*ce95e1b3SDavid du Colombier * bit reg
1149*ce95e1b3SDavid du Colombier * 7 F1
1150*ce95e1b3SDavid du Colombier * 8 F2
1151*ce95e1b3SDavid du Colombier * ... ...
1152*ce95e1b3SDavid du Colombier * 31 F25
1153*ce95e1b3SDavid du Colombier */
1154*ce95e1b3SDavid du Colombier long
FtoB(int f)1155*ce95e1b3SDavid du Colombier FtoB(int f)
1156*ce95e1b3SDavid du Colombier {
1157*ce95e1b3SDavid du Colombier
1158*ce95e1b3SDavid du Colombier if(f < 1 || f > 25)
1159*ce95e1b3SDavid du Colombier return 0;
1160*ce95e1b3SDavid du Colombier return 1L << (f + 6);
1161*ce95e1b3SDavid du Colombier }
1162*ce95e1b3SDavid du Colombier
1163*ce95e1b3SDavid du Colombier int
BtoF(long b)1164*ce95e1b3SDavid du Colombier BtoF(long b)
1165*ce95e1b3SDavid du Colombier {
1166*ce95e1b3SDavid du Colombier
1167*ce95e1b3SDavid du Colombier b &= 0x03ffff80L;
1168*ce95e1b3SDavid du Colombier if(b == 0)
1169*ce95e1b3SDavid du Colombier return 0;
1170*ce95e1b3SDavid du Colombier return bitno(b) - 6;
1171*ce95e1b3SDavid du Colombier }
1172