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