xref: /plan9/sys/src/cmd/vc/reg.c (revision 375daca8932d0755549a5f8e4d068a24a49927d4)
13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier 
3219b2ee8SDavid du Colombier void	addsplits(void);
4219b2ee8SDavid du Colombier 
53e12c5d1SDavid du Colombier Reg*
rega(void)63e12c5d1SDavid du Colombier rega(void)
73e12c5d1SDavid du Colombier {
83e12c5d1SDavid du Colombier 	Reg *r;
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier 	r = freer;
113e12c5d1SDavid du Colombier 	if(r == R) {
127dd7cddfSDavid du Colombier 		r = alloc(sizeof(*r));
133e12c5d1SDavid du Colombier 	} else
143e12c5d1SDavid du Colombier 		freer = r->link;
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier 	*r = zreg;
173e12c5d1SDavid du Colombier 	return r;
183e12c5d1SDavid du Colombier }
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier int
rcmp(const void * a1,const void * a2)217dd7cddfSDavid du Colombier rcmp(const void *a1, const void *a2)
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier 	Rgn *p1, *p2;
243e12c5d1SDavid du Colombier 	int c1, c2;
253e12c5d1SDavid du Colombier 
267dd7cddfSDavid du Colombier 	p1 = (Rgn*)a1;
277dd7cddfSDavid du Colombier 	p2 = (Rgn*)a2;
283e12c5d1SDavid du Colombier 	c1 = p2->cost;
293e12c5d1SDavid du Colombier 	c2 = p1->cost;
303e12c5d1SDavid du Colombier 	if(c1 -= c2)
313e12c5d1SDavid du Colombier 		return c1;
323e12c5d1SDavid du Colombier 	return p2->varno - p1->varno;
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier 
353e12c5d1SDavid du Colombier void
regopt(Prog * p)363e12c5d1SDavid du Colombier regopt(Prog *p)
373e12c5d1SDavid du Colombier {
383e12c5d1SDavid du Colombier 	Reg *r, *r1, *r2;
39219b2ee8SDavid du Colombier 	Prog *p1;
403e12c5d1SDavid du Colombier 	int i, z;
417dd7cddfSDavid du Colombier 	long initpc, val, npc;
423e12c5d1SDavid du Colombier 	ulong vreg;
433e12c5d1SDavid du Colombier 	Bits bit;
443e12c5d1SDavid du Colombier 	struct
453e12c5d1SDavid du Colombier 	{
463e12c5d1SDavid du Colombier 		long	m;
473e12c5d1SDavid du Colombier 		long	c;
483e12c5d1SDavid du Colombier 		Reg*	p;
493e12c5d1SDavid du Colombier 	} log5[6], *lp;
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier 	firstr = R;
523e12c5d1SDavid du Colombier 	lastr = R;
533e12c5d1SDavid du Colombier 	nvar = 0;
543e12c5d1SDavid du Colombier 	regbits = 0;
553e12c5d1SDavid du Colombier 	for(z=0; z<BITS; z++) {
563e12c5d1SDavid du Colombier 		externs.b[z] = 0;
573e12c5d1SDavid du Colombier 		params.b[z] = 0;
583e12c5d1SDavid du Colombier 		consts.b[z] = 0;
593e12c5d1SDavid du Colombier 		addrs.b[z] = 0;
603e12c5d1SDavid du Colombier 	}
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier 	/*
633e12c5d1SDavid du Colombier 	 * pass 1
643e12c5d1SDavid du Colombier 	 * build aux data structure
653e12c5d1SDavid du Colombier 	 * allocate pcs
663e12c5d1SDavid du Colombier 	 * find use and set of variables
673e12c5d1SDavid du Colombier 	 */
683e12c5d1SDavid du Colombier 	val = 5L * 5L * 5L * 5L * 5L;
693e12c5d1SDavid du Colombier 	lp = log5;
703e12c5d1SDavid du Colombier 	for(i=0; i<5; i++) {
713e12c5d1SDavid du Colombier 		lp->m = val;
723e12c5d1SDavid du Colombier 		lp->c = 0;
733e12c5d1SDavid du Colombier 		lp->p = R;
743e12c5d1SDavid du Colombier 		val /= 5L;
753e12c5d1SDavid du Colombier 		lp++;
763e12c5d1SDavid du Colombier 	}
773e12c5d1SDavid du Colombier 	val = 0;
783e12c5d1SDavid du Colombier 	for(; p != P; p = p->link) {
793e12c5d1SDavid du Colombier 		switch(p->as) {
803e12c5d1SDavid du Colombier 		case ADATA:
813e12c5d1SDavid du Colombier 		case AGLOBL:
823e12c5d1SDavid du Colombier 		case ANAME:
83*375daca8SDavid du Colombier 		case ASIGNAME:
843e12c5d1SDavid du Colombier 			continue;
853e12c5d1SDavid du Colombier 		}
863e12c5d1SDavid du Colombier 		r = rega();
873e12c5d1SDavid du Colombier 		if(firstr == R) {
883e12c5d1SDavid du Colombier 			firstr = r;
893e12c5d1SDavid du Colombier 			lastr = r;
903e12c5d1SDavid du Colombier 		} else {
913e12c5d1SDavid du Colombier 			lastr->link = r;
923e12c5d1SDavid du Colombier 			r->p1 = lastr;
933e12c5d1SDavid du Colombier 			lastr->s1 = r;
943e12c5d1SDavid du Colombier 			lastr = r;
953e12c5d1SDavid du Colombier 		}
963e12c5d1SDavid du Colombier 		r->prog = p;
973e12c5d1SDavid du Colombier 		r->pc = val;
983e12c5d1SDavid du Colombier 		val++;
993e12c5d1SDavid du Colombier 
1003e12c5d1SDavid du Colombier 		lp = log5;
1013e12c5d1SDavid du Colombier 		for(i=0; i<5; i++) {
1023e12c5d1SDavid du Colombier 			lp->c--;
1033e12c5d1SDavid du Colombier 			if(lp->c <= 0) {
1043e12c5d1SDavid du Colombier 				lp->c = lp->m;
1053e12c5d1SDavid du Colombier 				if(lp->p != R)
1063e12c5d1SDavid du Colombier 					lp->p->log5 = r;
1073e12c5d1SDavid du Colombier 				lp->p = r;
1083e12c5d1SDavid du Colombier 				(lp+1)->c = 0;
1093e12c5d1SDavid du Colombier 				break;
1103e12c5d1SDavid du Colombier 			}
1113e12c5d1SDavid du Colombier 			lp++;
1123e12c5d1SDavid du Colombier 		}
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 		r1 = r->p1;
1153e12c5d1SDavid du Colombier 		if(r1 != R)
1163e12c5d1SDavid du Colombier 		switch(r1->prog->as) {
1173e12c5d1SDavid du Colombier 		case ARET:
1183e12c5d1SDavid du Colombier 		case AJMP:
1193e12c5d1SDavid du Colombier 		case ARFE:
1203e12c5d1SDavid du Colombier 			r->p1 = R;
1213e12c5d1SDavid du Colombier 			r1->s1 = R;
1223e12c5d1SDavid du Colombier 		}
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier 		/*
1253e12c5d1SDavid du Colombier 		 * left side always read
1263e12c5d1SDavid du Colombier 		 */
1273e12c5d1SDavid du Colombier 		bit = mkvar(&p->from, p->as==AMOVW);
1283e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
1293e12c5d1SDavid du Colombier 			r->use1.b[z] |= bit.b[z];
1303e12c5d1SDavid du Colombier 
1313e12c5d1SDavid du Colombier 		/*
1323e12c5d1SDavid du Colombier 		 * right side depends on opcode
1333e12c5d1SDavid du Colombier 		 */
1343e12c5d1SDavid du Colombier 		bit = mkvar(&p->to, 0);
1353e12c5d1SDavid du Colombier 		if(bany(&bit))
1363e12c5d1SDavid du Colombier 		switch(p->as) {
1373e12c5d1SDavid du Colombier 		default:
1383e12c5d1SDavid du Colombier 			diag(Z, "reg: unknown asop: %A", p->as);
1393e12c5d1SDavid du Colombier 			break;
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier 		/*
1423e12c5d1SDavid du Colombier 		 * right side write
1433e12c5d1SDavid du Colombier 		 */
1443e12c5d1SDavid du Colombier 		case ANOP:
1453e12c5d1SDavid du Colombier 		case AMOVB:
1463e12c5d1SDavid du Colombier 		case AMOVBU:
1473e12c5d1SDavid du Colombier 		case AMOVH:
1483e12c5d1SDavid du Colombier 		case AMOVHU:
1493e12c5d1SDavid du Colombier 		case AMOVW:
1503e12c5d1SDavid du Colombier 		case AMOVF:
1513e12c5d1SDavid du Colombier 		case AMOVD:
1523e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++)
1533e12c5d1SDavid du Colombier 				r->set.b[z] |= bit.b[z];
1543e12c5d1SDavid du Colombier 			break;
1553e12c5d1SDavid du Colombier 
1563e12c5d1SDavid du Colombier 		/*
1573e12c5d1SDavid du Colombier 		 * funny
1583e12c5d1SDavid du Colombier 		 */
1593e12c5d1SDavid du Colombier 		case AJAL:
1603e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++)
1613e12c5d1SDavid du Colombier 				addrs.b[z] |= bit.b[z];
1623e12c5d1SDavid du Colombier 			break;
1633e12c5d1SDavid du Colombier 		}
1643e12c5d1SDavid du Colombier 	}
1653e12c5d1SDavid du Colombier 	if(firstr == R)
1663e12c5d1SDavid du Colombier 		return;
1673e12c5d1SDavid du Colombier 	initpc = pc - val;
1687dd7cddfSDavid du Colombier 	npc = val;
1693e12c5d1SDavid du Colombier 
1703e12c5d1SDavid du Colombier 	/*
1713e12c5d1SDavid du Colombier 	 * pass 2
1723e12c5d1SDavid du Colombier 	 * turn branch references to pointers
1733e12c5d1SDavid du Colombier 	 * build back pointers
1743e12c5d1SDavid du Colombier 	 */
1753e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
1763e12c5d1SDavid du Colombier 		p = r->prog;
1773e12c5d1SDavid du Colombier 		if(p->to.type == D_BRANCH) {
1783e12c5d1SDavid du Colombier 			val = p->to.offset - initpc;
1793e12c5d1SDavid du Colombier 			r1 = firstr;
1803e12c5d1SDavid du Colombier 			while(r1 != R) {
1813e12c5d1SDavid du Colombier 				r2 = r1->log5;
1823e12c5d1SDavid du Colombier 				if(r2 != R && val >= r2->pc) {
1833e12c5d1SDavid du Colombier 					r1 = r2;
1843e12c5d1SDavid du Colombier 					continue;
1853e12c5d1SDavid du Colombier 				}
1863e12c5d1SDavid du Colombier 				if(r1->pc == val)
1873e12c5d1SDavid du Colombier 					break;
1883e12c5d1SDavid du Colombier 				r1 = r1->link;
1893e12c5d1SDavid du Colombier 			}
1903e12c5d1SDavid du Colombier 			if(r1 == R) {
1913e12c5d1SDavid du Colombier 				nearln = p->lineno;
1923e12c5d1SDavid du Colombier 				diag(Z, "ref not found\n%P", p);
1933e12c5d1SDavid du Colombier 				continue;
1943e12c5d1SDavid du Colombier 			}
1953e12c5d1SDavid du Colombier 			if(r1 == r) {
1963e12c5d1SDavid du Colombier 				nearln = p->lineno;
1973e12c5d1SDavid du Colombier 				diag(Z, "ref to self\n%P", p);
1983e12c5d1SDavid du Colombier 				continue;
1993e12c5d1SDavid du Colombier 			}
2003e12c5d1SDavid du Colombier 			r->s2 = r1;
2013e12c5d1SDavid du Colombier 			r->p2link = r1->p2;
2023e12c5d1SDavid du Colombier 			r1->p2 = r;
2033e12c5d1SDavid du Colombier 		}
2043e12c5d1SDavid du Colombier 	}
2053e12c5d1SDavid du Colombier 	if(debug['R']) {
2063e12c5d1SDavid du Colombier 		p = firstr->prog;
2073e12c5d1SDavid du Colombier 		print("\n%L %D\n", p->lineno, &p->from);
2083e12c5d1SDavid du Colombier 	}
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier 	/*
2113e12c5d1SDavid du Colombier 	 * pass 2.5
2123e12c5d1SDavid du Colombier 	 * find looping structure
2133e12c5d1SDavid du Colombier 	 */
2143e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2153e12c5d1SDavid du Colombier 		r->active = 0;
2163e12c5d1SDavid du Colombier 	change = 0;
2177dd7cddfSDavid du Colombier 	loopit(firstr, npc);
2183e12c5d1SDavid du Colombier 
2193e12c5d1SDavid du Colombier 	/*
2203e12c5d1SDavid du Colombier 	 * pass 3
2213e12c5d1SDavid du Colombier 	 * iterate propagating usage
2223e12c5d1SDavid du Colombier 	 * 	back until flow graph is complete
2233e12c5d1SDavid du Colombier 	 */
2243e12c5d1SDavid du Colombier loop1:
2253e12c5d1SDavid du Colombier 	change = 0;
2263e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2273e12c5d1SDavid du Colombier 		r->active = 0;
2283e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2293e12c5d1SDavid du Colombier 		if(r->prog->as == ARET)
2303e12c5d1SDavid du Colombier 			prop(r, zbits, zbits);
2313e12c5d1SDavid du Colombier loop11:
2323e12c5d1SDavid du Colombier 	/* pick up unreachable code */
2333e12c5d1SDavid du Colombier 	i = 0;
2343e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r1) {
2353e12c5d1SDavid du Colombier 		r1 = r->link;
2363e12c5d1SDavid du Colombier 		if(r1 && r1->active && !r->active) {
2373e12c5d1SDavid du Colombier 			prop(r, zbits, zbits);
2383e12c5d1SDavid du Colombier 			i = 1;
2393e12c5d1SDavid du Colombier 		}
2403e12c5d1SDavid du Colombier 	}
2413e12c5d1SDavid du Colombier 	if(i)
2423e12c5d1SDavid du Colombier 		goto loop11;
2433e12c5d1SDavid du Colombier 	if(change)
2443e12c5d1SDavid du Colombier 		goto loop1;
2453e12c5d1SDavid du Colombier 
2463e12c5d1SDavid du Colombier 
2473e12c5d1SDavid du Colombier 	/*
2483e12c5d1SDavid du Colombier 	 * pass 4
2493e12c5d1SDavid du Colombier 	 * iterate propagating register/variable synchrony
2503e12c5d1SDavid du Colombier 	 * 	forward until graph is complete
2513e12c5d1SDavid du Colombier 	 */
2523e12c5d1SDavid du Colombier loop2:
2533e12c5d1SDavid du Colombier 	change = 0;
2543e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2553e12c5d1SDavid du Colombier 		r->active = 0;
2563e12c5d1SDavid du Colombier 	synch(firstr, zbits);
2573e12c5d1SDavid du Colombier 	if(change)
2583e12c5d1SDavid du Colombier 		goto loop2;
2593e12c5d1SDavid du Colombier 
260219b2ee8SDavid du Colombier 	addsplits();
261219b2ee8SDavid du Colombier 
262219b2ee8SDavid du Colombier 	if(debug['R'] && debug['v']) {
263219b2ee8SDavid du Colombier 		print("\nprop structure:\n");
264219b2ee8SDavid du Colombier 		for(r = firstr; r != R; r = r->link) {
2657dd7cddfSDavid du Colombier 			print("%ld:%P", r->loop, r->prog);
266219b2ee8SDavid du Colombier 			for(z=0; z<BITS; z++)
267219b2ee8SDavid du Colombier 				bit.b[z] = r->set.b[z] |
268219b2ee8SDavid du Colombier 					r->refahead.b[z] | r->calahead.b[z] |
269219b2ee8SDavid du Colombier 					r->refbehind.b[z] | r->calbehind.b[z] |
270219b2ee8SDavid du Colombier 					r->use1.b[z] | r->use2.b[z];
271219b2ee8SDavid du Colombier 			if(bany(&bit)) {
2729a747e4fSDavid du Colombier 				print("\t");
273219b2ee8SDavid du Colombier 				if(bany(&r->use1))
274219b2ee8SDavid du Colombier 					print(" u1=%B", r->use1);
275219b2ee8SDavid du Colombier 				if(bany(&r->use2))
276219b2ee8SDavid du Colombier 					print(" u2=%B", r->use2);
277219b2ee8SDavid du Colombier 				if(bany(&r->set))
278219b2ee8SDavid du Colombier 					print(" st=%B", r->set);
279219b2ee8SDavid du Colombier 				if(bany(&r->refahead))
280219b2ee8SDavid du Colombier 					print(" ra=%B", r->refahead);
281219b2ee8SDavid du Colombier 				if(bany(&r->calahead))
282219b2ee8SDavid du Colombier 					print(" ca=%B", r->calahead);
283219b2ee8SDavid du Colombier 				if(bany(&r->refbehind))
284219b2ee8SDavid du Colombier 					print(" rb=%B", r->refbehind);
285219b2ee8SDavid du Colombier 				if(bany(&r->calbehind))
286219b2ee8SDavid du Colombier 					print(" cb=%B", r->calbehind);
2877dd7cddfSDavid du Colombier 				if(bany(&r->regdiff))
2887dd7cddfSDavid du Colombier 					print(" rd=%B", r->regdiff);
289219b2ee8SDavid du Colombier 			}
290219b2ee8SDavid du Colombier 			print("\n");
291219b2ee8SDavid du Colombier 		}
292219b2ee8SDavid du Colombier 	}
2933e12c5d1SDavid du Colombier 
2943e12c5d1SDavid du Colombier 	/*
2953e12c5d1SDavid du Colombier 	 * pass 5
2963e12c5d1SDavid du Colombier 	 * isolate regions
2973e12c5d1SDavid du Colombier 	 * calculate costs (paint1)
2983e12c5d1SDavid du Colombier 	 */
2993e12c5d1SDavid du Colombier 	r = firstr;
3003e12c5d1SDavid du Colombier 	if(r) {
3013e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
3023e12c5d1SDavid du Colombier 			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
3033e12c5d1SDavid du Colombier 			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
3043e12c5d1SDavid du Colombier 		if(bany(&bit)) {
3053e12c5d1SDavid du Colombier 			nearln = r->prog->lineno;
3063e12c5d1SDavid du Colombier 			warn(Z, "used and not set: %B", bit);
3073e12c5d1SDavid du Colombier 			if(debug['R'] && !debug['w'])
3083e12c5d1SDavid du Colombier 				print("used and not set: %B\n", bit);
3093e12c5d1SDavid du Colombier 		}
3103e12c5d1SDavid du Colombier 	}
311219b2ee8SDavid du Colombier 
3123e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link)
3133e12c5d1SDavid du Colombier 		r->act = zbits;
3143e12c5d1SDavid du Colombier 	rgp = region;
3153e12c5d1SDavid du Colombier 	nregion = 0;
3163e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
3173e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
3183e12c5d1SDavid du Colombier 			bit.b[z] = r->set.b[z] &
3193e12c5d1SDavid du Colombier 			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
3203e12c5d1SDavid du Colombier 		if(bany(&bit)) {
3213e12c5d1SDavid du Colombier 			nearln = r->prog->lineno;
3223e12c5d1SDavid du Colombier 			warn(Z, "set and not used: %B", bit);
3233e12c5d1SDavid du Colombier 			if(debug['R'])
324219b2ee8SDavid du Colombier 				print("set and not used: %B\n", bit);
3253e12c5d1SDavid du Colombier 			excise(r);
3263e12c5d1SDavid du Colombier 		}
3273e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
3283e12c5d1SDavid du Colombier 			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
3293e12c5d1SDavid du Colombier 		while(bany(&bit)) {
3303e12c5d1SDavid du Colombier 			i = bnum(bit);
3313e12c5d1SDavid du Colombier 			rgp->enter = r;
3323e12c5d1SDavid du Colombier 			rgp->varno = i;
3333e12c5d1SDavid du Colombier 			change = 0;
3343e12c5d1SDavid du Colombier 			if(debug['R'] && debug['v'])
3353e12c5d1SDavid du Colombier 				print("\n");
3363e12c5d1SDavid du Colombier 			paint1(r, i);
3373e12c5d1SDavid du Colombier 			bit.b[i/32] &= ~(1L<<(i%32));
3383e12c5d1SDavid du Colombier 			if(change <= 0) {
3393e12c5d1SDavid du Colombier 				if(debug['R'])
3403e12c5d1SDavid du Colombier 					print("%L $%d: %B\n",
3413e12c5d1SDavid du Colombier 						r->prog->lineno, change, blsh(i));
3423e12c5d1SDavid du Colombier 				continue;
3433e12c5d1SDavid du Colombier 			}
3443e12c5d1SDavid du Colombier 			rgp->cost = change;
3453e12c5d1SDavid du Colombier 			nregion++;
3463e12c5d1SDavid du Colombier 			if(nregion >= NRGN) {
3473e12c5d1SDavid du Colombier 				warn(Z, "too many regions");
3483e12c5d1SDavid du Colombier 				goto brk;
3493e12c5d1SDavid du Colombier 			}
3503e12c5d1SDavid du Colombier 			rgp++;
3513e12c5d1SDavid du Colombier 		}
3523e12c5d1SDavid du Colombier 	}
3533e12c5d1SDavid du Colombier brk:
3543e12c5d1SDavid du Colombier 	qsort(region, nregion, sizeof(region[0]), rcmp);
3553e12c5d1SDavid du Colombier 
3563e12c5d1SDavid du Colombier 	/*
3573e12c5d1SDavid du Colombier 	 * pass 6
3583e12c5d1SDavid du Colombier 	 * determine used registers (paint2)
3593e12c5d1SDavid du Colombier 	 * replace code (paint3)
3603e12c5d1SDavid du Colombier 	 */
3613e12c5d1SDavid du Colombier 	rgp = region;
3623e12c5d1SDavid du Colombier 	for(i=0; i<nregion; i++) {
3633e12c5d1SDavid du Colombier 		bit = blsh(rgp->varno);
3643e12c5d1SDavid du Colombier 		vreg = paint2(rgp->enter, rgp->varno);
3653e12c5d1SDavid du Colombier 		vreg = allreg(vreg, rgp);
3663e12c5d1SDavid du Colombier 		if(debug['R']) {
3673e12c5d1SDavid du Colombier 			if(rgp->regno >= NREG)
3683e12c5d1SDavid du Colombier 				print("%L $%d F%d: %B\n",
3693e12c5d1SDavid du Colombier 					rgp->enter->prog->lineno,
3703e12c5d1SDavid du Colombier 					rgp->cost,
3713e12c5d1SDavid du Colombier 					rgp->regno-NREG,
3723e12c5d1SDavid du Colombier 					bit);
3733e12c5d1SDavid du Colombier 			else
3743e12c5d1SDavid du Colombier 				print("%L $%d R%d: %B\n",
3753e12c5d1SDavid du Colombier 					rgp->enter->prog->lineno,
3763e12c5d1SDavid du Colombier 					rgp->cost,
3773e12c5d1SDavid du Colombier 					rgp->regno,
3783e12c5d1SDavid du Colombier 					bit);
3793e12c5d1SDavid du Colombier 		}
3803e12c5d1SDavid du Colombier 		if(rgp->regno != 0)
3813e12c5d1SDavid du Colombier 			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
3823e12c5d1SDavid du Colombier 		rgp++;
3833e12c5d1SDavid du Colombier 	}
3843e12c5d1SDavid du Colombier 	/*
3853e12c5d1SDavid du Colombier 	 * pass 7
3863e12c5d1SDavid du Colombier 	 * peep-hole on basic block
3873e12c5d1SDavid du Colombier 	 */
3883e12c5d1SDavid du Colombier 	if(!debug['R'] || debug['P'])
3893e12c5d1SDavid du Colombier 		peep();
3903e12c5d1SDavid du Colombier 
3913e12c5d1SDavid du Colombier 	/*
3923e12c5d1SDavid du Colombier 	 * pass 8
3933e12c5d1SDavid du Colombier 	 * recalculate pc
3943e12c5d1SDavid du Colombier 	 */
3953e12c5d1SDavid du Colombier 	val = initpc;
3963e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r1) {
3973e12c5d1SDavid du Colombier 		r->pc = val;
3983e12c5d1SDavid du Colombier 		p = r->prog;
399219b2ee8SDavid du Colombier 		p1 = P;
4003e12c5d1SDavid du Colombier 		r1 = r->link;
401219b2ee8SDavid du Colombier 		if(r1 != R)
402219b2ee8SDavid du Colombier 			p1 = r1->prog;
403219b2ee8SDavid du Colombier 		for(; p != p1; p = p->link) {
4043e12c5d1SDavid du Colombier 			switch(p->as) {
4053e12c5d1SDavid du Colombier 			default:
4063e12c5d1SDavid du Colombier 				val++;
407219b2ee8SDavid du Colombier 				break;
4083e12c5d1SDavid du Colombier 
409219b2ee8SDavid du Colombier 			case ANOP:
4103e12c5d1SDavid du Colombier 			case ADATA:
4113e12c5d1SDavid du Colombier 			case AGLOBL:
4123e12c5d1SDavid du Colombier 			case ANAME:
413*375daca8SDavid du Colombier 			case ASIGNAME:
414219b2ee8SDavid du Colombier 				break;
4153e12c5d1SDavid du Colombier 			}
4163e12c5d1SDavid du Colombier 		}
417219b2ee8SDavid du Colombier 	}
418219b2ee8SDavid du Colombier 	pc = val;
4193e12c5d1SDavid du Colombier 
4203e12c5d1SDavid du Colombier 	/*
4213e12c5d1SDavid du Colombier 	 * fix up branches
4223e12c5d1SDavid du Colombier 	 */
4233e12c5d1SDavid du Colombier 	if(debug['R'])
4243e12c5d1SDavid du Colombier 		if(bany(&addrs))
4253e12c5d1SDavid du Colombier 			print("addrs: %B\n", addrs);
4263e12c5d1SDavid du Colombier 
4273e12c5d1SDavid du Colombier 	r1 = 0; /* set */
4283e12c5d1SDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
4293e12c5d1SDavid du Colombier 		p = r->prog;
4303e12c5d1SDavid du Colombier 		if(p->to.type == D_BRANCH)
4313e12c5d1SDavid du Colombier 			p->to.offset = r->s2->pc;
4323e12c5d1SDavid du Colombier 		r1 = r;
4333e12c5d1SDavid du Colombier 	}
434219b2ee8SDavid du Colombier 
435219b2ee8SDavid du Colombier 	/*
436219b2ee8SDavid du Colombier 	 * last pass
437219b2ee8SDavid du Colombier 	 * eliminate nops
438219b2ee8SDavid du Colombier 	 * free aux structures
439219b2ee8SDavid du Colombier 	 */
440219b2ee8SDavid du Colombier 	for(p = firstr->prog; p != P; p = p->link){
441219b2ee8SDavid du Colombier 		while(p->link && p->link->as == ANOP)
442219b2ee8SDavid du Colombier 			p->link = p->link->link;
443219b2ee8SDavid du Colombier 	}
4443e12c5d1SDavid du Colombier 	if(r1 != R) {
4453e12c5d1SDavid du Colombier 		r1->link = freer;
4463e12c5d1SDavid du Colombier 		freer = firstr;
4473e12c5d1SDavid du Colombier 	}
4483e12c5d1SDavid du Colombier }
4493e12c5d1SDavid du Colombier 
450219b2ee8SDavid du Colombier void
addsplits(void)451219b2ee8SDavid du Colombier addsplits(void)
452219b2ee8SDavid du Colombier {
453219b2ee8SDavid du Colombier 	Reg *r, *r1;
454219b2ee8SDavid du Colombier 	int z, i;
455219b2ee8SDavid du Colombier 	Bits bit;
456219b2ee8SDavid du Colombier 
457219b2ee8SDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
458219b2ee8SDavid du Colombier 		if(r->loop > 1)
459219b2ee8SDavid du Colombier 			continue;
460219b2ee8SDavid du Colombier 		if(r->prog->as == AJAL)
461219b2ee8SDavid du Colombier 			continue;
462219b2ee8SDavid du Colombier 		for(r1 = r->p2; r1 != R; r1 = r1->p2link) {
463219b2ee8SDavid du Colombier 			if(r1->loop <= 1)
464219b2ee8SDavid du Colombier 				continue;
465219b2ee8SDavid du Colombier 			for(z=0; z<BITS; z++)
466219b2ee8SDavid du Colombier 				bit.b[z] = r1->calbehind.b[z] &
467219b2ee8SDavid du Colombier 					(r->refahead.b[z] | r->use1.b[z] | r->use2.b[z]) &
468219b2ee8SDavid du Colombier 					~(r->calahead.b[z] & addrs.b[z]);
469219b2ee8SDavid du Colombier 			while(bany(&bit)) {
470219b2ee8SDavid du Colombier 				i = bnum(bit);
471219b2ee8SDavid du Colombier 				bit.b[i/32] &= ~(1L << (i%32));
472219b2ee8SDavid du Colombier 			}
473219b2ee8SDavid du Colombier 		}
474219b2ee8SDavid du Colombier 	}
475219b2ee8SDavid du Colombier }
476219b2ee8SDavid du Colombier 
4773e12c5d1SDavid du Colombier /*
4783e12c5d1SDavid du Colombier  * add mov b,rn
4793e12c5d1SDavid du Colombier  * just after r
4803e12c5d1SDavid du Colombier  */
4813e12c5d1SDavid du Colombier void
addmove(Reg * r,int bn,int rn,int f)4823e12c5d1SDavid du Colombier addmove(Reg *r, int bn, int rn, int f)
4833e12c5d1SDavid du Colombier {
4843e12c5d1SDavid du Colombier 	Prog *p, *p1;
4853e12c5d1SDavid du Colombier 	Adr *a;
4863e12c5d1SDavid du Colombier 	Var *v;
4873e12c5d1SDavid du Colombier 
4887dd7cddfSDavid du Colombier 	p1 = alloc(sizeof(*p1));
4893e12c5d1SDavid du Colombier 	*p1 = zprog;
4903e12c5d1SDavid du Colombier 	p = r->prog;
4913e12c5d1SDavid du Colombier 
4923e12c5d1SDavid du Colombier 	p1->link = p->link;
4933e12c5d1SDavid du Colombier 	p->link = p1;
4943e12c5d1SDavid du Colombier 	p1->lineno = p->lineno;
4953e12c5d1SDavid du Colombier 
4963e12c5d1SDavid du Colombier 	v = var + bn;
4973e12c5d1SDavid du Colombier 
4983e12c5d1SDavid du Colombier 	a = &p1->to;
4993e12c5d1SDavid du Colombier 	a->sym = v->sym;
5003e12c5d1SDavid du Colombier 	a->name = v->name;
5013e12c5d1SDavid du Colombier 	a->offset = v->offset;
5023e12c5d1SDavid du Colombier 	a->etype = v->etype;
5033e12c5d1SDavid du Colombier 	a->type = D_OREG;
5043e12c5d1SDavid du Colombier 	if(a->etype == TARRAY || a->sym == S)
5053e12c5d1SDavid du Colombier 		a->type = D_CONST;
5063e12c5d1SDavid du Colombier 
5073e12c5d1SDavid du Colombier 	p1->as = AMOVW;
5083e12c5d1SDavid du Colombier 	if(v->etype == TCHAR || v->etype == TUCHAR)
5093e12c5d1SDavid du Colombier 		p1->as = AMOVB;
5103e12c5d1SDavid du Colombier 	if(v->etype == TSHORT || v->etype == TUSHORT)
5113e12c5d1SDavid du Colombier 		p1->as = AMOVH;
5123e12c5d1SDavid du Colombier 	if(v->etype == TFLOAT)
5133e12c5d1SDavid du Colombier 		p1->as = AMOVF;
5143e12c5d1SDavid du Colombier 	if(v->etype == TDOUBLE)
5153e12c5d1SDavid du Colombier 		p1->as = AMOVD;
5163e12c5d1SDavid du Colombier 
5173e12c5d1SDavid du Colombier 	p1->from.type = D_REG;
5183e12c5d1SDavid du Colombier 	p1->from.reg = rn;
5193e12c5d1SDavid du Colombier 	if(rn >= NREG) {
5203e12c5d1SDavid du Colombier 		p1->from.type = D_FREG;
5213e12c5d1SDavid du Colombier 		p1->from.reg = rn-NREG;
5223e12c5d1SDavid du Colombier 	}
5233e12c5d1SDavid du Colombier 	if(!f) {
5243e12c5d1SDavid du Colombier 		p1->from = *a;
5253e12c5d1SDavid du Colombier 		*a = zprog.from;
5263e12c5d1SDavid du Colombier 		a->type = D_REG;
5273e12c5d1SDavid du Colombier 		a->reg = rn;
5283e12c5d1SDavid du Colombier 		if(rn >= NREG) {
5293e12c5d1SDavid du Colombier 			a->type = D_FREG;
5303e12c5d1SDavid du Colombier 			a->reg = rn-NREG;
5313e12c5d1SDavid du Colombier 		}
5323e12c5d1SDavid du Colombier 		if(v->etype == TUCHAR)
5333e12c5d1SDavid du Colombier 			p1->as = AMOVBU;
5343e12c5d1SDavid du Colombier 		if(v->etype == TUSHORT)
5353e12c5d1SDavid du Colombier 			p1->as = AMOVHU;
5363e12c5d1SDavid du Colombier 	}
5373e12c5d1SDavid du Colombier 	if(debug['R'])
5389a747e4fSDavid du Colombier 		print("%P\t.a%P\n", p, p1);
5393e12c5d1SDavid du Colombier }
5403e12c5d1SDavid du Colombier 
5413e12c5d1SDavid du Colombier Bits
mkvar(Adr * a,int docon)5423e12c5d1SDavid du Colombier mkvar(Adr *a, int docon)
5433e12c5d1SDavid du Colombier {
5443e12c5d1SDavid du Colombier 	Var *v;
5453e12c5d1SDavid du Colombier 	int i, t, n, et, z;
5463e12c5d1SDavid du Colombier 	long o;
5473e12c5d1SDavid du Colombier 	Bits bit;
5483e12c5d1SDavid du Colombier 	Sym *s;
5493e12c5d1SDavid du Colombier 
5503e12c5d1SDavid du Colombier 	t = a->type;
5513e12c5d1SDavid du Colombier 	if(t == D_REG && a->reg != NREG)
5523e12c5d1SDavid du Colombier 		regbits |= RtoB(a->reg);
5533e12c5d1SDavid du Colombier 	if(t == D_FREG && a->reg != NREG)
5543e12c5d1SDavid du Colombier 		regbits |= FtoB(a->reg);
5553e12c5d1SDavid du Colombier 	s = a->sym;
5563e12c5d1SDavid du Colombier 	o = a->offset;
5573e12c5d1SDavid du Colombier 	et = a->etype;
5583e12c5d1SDavid du Colombier 	if(s == S) {
5593e12c5d1SDavid du Colombier 		if(t != D_CONST || !docon || a->reg != NREG)
5603e12c5d1SDavid du Colombier 			goto none;
5613e12c5d1SDavid du Colombier 		et = TLONG;
5623e12c5d1SDavid du Colombier 	}
5633e12c5d1SDavid du Colombier 	if(t == D_CONST) {
5643e12c5d1SDavid du Colombier 		if(s == S && sval(o))
5653e12c5d1SDavid du Colombier 			goto none;
5663e12c5d1SDavid du Colombier 	}
5673e12c5d1SDavid du Colombier 
5683e12c5d1SDavid du Colombier 	n = a->name;
5693e12c5d1SDavid du Colombier 	v = var;
5703e12c5d1SDavid du Colombier 	for(i=0; i<nvar; i++) {
5713e12c5d1SDavid du Colombier 		if(s == v->sym)
5723e12c5d1SDavid du Colombier 		if(n == v->name)
5733e12c5d1SDavid du Colombier 		if(o == v->offset)
5743e12c5d1SDavid du Colombier 			goto out;
5753e12c5d1SDavid du Colombier 		v++;
5763e12c5d1SDavid du Colombier 	}
5773e12c5d1SDavid du Colombier 	if(s)
5783e12c5d1SDavid du Colombier 		if(s->name[0] == '.')
5793e12c5d1SDavid du Colombier 			goto none;
5803e12c5d1SDavid du Colombier 	if(nvar >= NVAR) {
5817dd7cddfSDavid du Colombier 		if(debug['w'] > 1 && s)
5823e12c5d1SDavid du Colombier 			warn(Z, "variable not optimized: %s", s->name);
5833e12c5d1SDavid du Colombier 		goto none;
5843e12c5d1SDavid du Colombier 	}
5853e12c5d1SDavid du Colombier 	i = nvar;
5863e12c5d1SDavid du Colombier 	nvar++;
5873e12c5d1SDavid du Colombier 	v = &var[i];
5883e12c5d1SDavid du Colombier 	v->sym = s;
5893e12c5d1SDavid du Colombier 	v->offset = o;
5903e12c5d1SDavid du Colombier 	v->etype = et;
5913e12c5d1SDavid du Colombier 	v->name = n;
5923e12c5d1SDavid du Colombier 	if(debug['R'])
5933e12c5d1SDavid du Colombier 		print("bit=%2d et=%2d %D\n", i, et, a);
5943e12c5d1SDavid du Colombier out:
5953e12c5d1SDavid du Colombier 	bit = blsh(i);
5963e12c5d1SDavid du Colombier 	if(n == D_EXTERN || n == D_STATIC)
5973e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
5983e12c5d1SDavid du Colombier 			externs.b[z] |= bit.b[z];
5993e12c5d1SDavid du Colombier 	if(n == D_PARAM)
6003e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
6013e12c5d1SDavid du Colombier 			params.b[z] |= bit.b[z];
602219b2ee8SDavid du Colombier 	if(v->etype != et || !typechlpfd[et])	/* funny punning */
6033e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
6043e12c5d1SDavid du Colombier 			addrs.b[z] |= bit.b[z];
6053e12c5d1SDavid du Colombier 	if(t == D_CONST) {
6063e12c5d1SDavid du Colombier 		if(s == S) {
6073e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++)
6083e12c5d1SDavid du Colombier 				consts.b[z] |= bit.b[z];
6093e12c5d1SDavid du Colombier 			return bit;
6103e12c5d1SDavid du Colombier 		}
6113e12c5d1SDavid du Colombier 		if(et != TARRAY)
6123e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++)
6133e12c5d1SDavid du Colombier 				addrs.b[z] |= bit.b[z];
6143e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
6153e12c5d1SDavid du Colombier 			params.b[z] |= bit.b[z];
6163e12c5d1SDavid du Colombier 		return bit;
6173e12c5d1SDavid du Colombier 	}
6183e12c5d1SDavid du Colombier 	if(t == D_OREG)
6193e12c5d1SDavid du Colombier 		return bit;
6203e12c5d1SDavid du Colombier 
6213e12c5d1SDavid du Colombier none:
6223e12c5d1SDavid du Colombier 	return zbits;
6233e12c5d1SDavid du Colombier }
6243e12c5d1SDavid du Colombier 
6253e12c5d1SDavid du Colombier void
prop(Reg * r,Bits ref,Bits cal)6263e12c5d1SDavid du Colombier prop(Reg *r, Bits ref, Bits cal)
6273e12c5d1SDavid du Colombier {
6283e12c5d1SDavid du Colombier 	Reg *r1, *r2;
6293e12c5d1SDavid du Colombier 	int z;
6303e12c5d1SDavid du Colombier 
6313e12c5d1SDavid du Colombier 	for(r1 = r; r1 != R; r1 = r1->p1) {
6323e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++) {
6333e12c5d1SDavid du Colombier 			ref.b[z] |= r1->refahead.b[z];
6343e12c5d1SDavid du Colombier 			if(ref.b[z] != r1->refahead.b[z]) {
6353e12c5d1SDavid du Colombier 				r1->refahead.b[z] = ref.b[z];
6363e12c5d1SDavid du Colombier 				change++;
6373e12c5d1SDavid du Colombier 			}
6383e12c5d1SDavid du Colombier 			cal.b[z] |= r1->calahead.b[z];
6393e12c5d1SDavid du Colombier 			if(cal.b[z] != r1->calahead.b[z]) {
6403e12c5d1SDavid du Colombier 				r1->calahead.b[z] = cal.b[z];
6413e12c5d1SDavid du Colombier 				change++;
6423e12c5d1SDavid du Colombier 			}
6433e12c5d1SDavid du Colombier 		}
6443e12c5d1SDavid du Colombier 		switch(r1->prog->as) {
6453e12c5d1SDavid du Colombier 		case AJAL:
6463e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++) {
6473e12c5d1SDavid du Colombier 				cal.b[z] |= ref.b[z] | externs.b[z];
6483e12c5d1SDavid du Colombier 				ref.b[z] = 0;
6493e12c5d1SDavid du Colombier 			}
6503e12c5d1SDavid du Colombier 			break;
6513e12c5d1SDavid du Colombier 
6523e12c5d1SDavid du Colombier 		case ATEXT:
6533e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++) {
6543e12c5d1SDavid du Colombier 				cal.b[z] = 0;
6553e12c5d1SDavid du Colombier 				ref.b[z] = 0;
6563e12c5d1SDavid du Colombier 			}
6573e12c5d1SDavid du Colombier 			break;
6583e12c5d1SDavid du Colombier 
6593e12c5d1SDavid du Colombier 		case ARET:
6603e12c5d1SDavid du Colombier 			for(z=0; z<BITS; z++) {
6613e12c5d1SDavid du Colombier 				cal.b[z] = externs.b[z];
6623e12c5d1SDavid du Colombier 				ref.b[z] = 0;
6633e12c5d1SDavid du Colombier 			}
6643e12c5d1SDavid du Colombier 		}
6653e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++) {
6663e12c5d1SDavid du Colombier 			ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
6673e12c5d1SDavid du Colombier 				r1->use1.b[z] | r1->use2.b[z];
6683e12c5d1SDavid du Colombier 			cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
6693e12c5d1SDavid du Colombier 			r1->refbehind.b[z] = ref.b[z];
6703e12c5d1SDavid du Colombier 			r1->calbehind.b[z] = cal.b[z];
6713e12c5d1SDavid du Colombier 		}
6723e12c5d1SDavid du Colombier 		if(r1->active)
6733e12c5d1SDavid du Colombier 			break;
6743e12c5d1SDavid du Colombier 		r1->active = 1;
6753e12c5d1SDavid du Colombier 	}
6763e12c5d1SDavid du Colombier 	for(; r != r1; r = r->p1)
6773e12c5d1SDavid du Colombier 		for(r2 = r->p2; r2 != R; r2 = r2->p2link)
6783e12c5d1SDavid du Colombier 			prop(r2, r->refbehind, r->calbehind);
6793e12c5d1SDavid du Colombier }
6803e12c5d1SDavid du Colombier 
6817dd7cddfSDavid du Colombier /*
6827dd7cddfSDavid du Colombier  * find looping structure
6837dd7cddfSDavid du Colombier  *
6847dd7cddfSDavid du Colombier  * 1) find reverse postordering
6857dd7cddfSDavid du Colombier  * 2) find approximate dominators,
6867dd7cddfSDavid du Colombier  *	the actual dominators if the flow graph is reducible
6877dd7cddfSDavid du Colombier  *	otherwise, dominators plus some other non-dominators.
6887dd7cddfSDavid du Colombier  *	See Matthew S. Hecht and Jeffrey D. Ullman,
6897dd7cddfSDavid du Colombier  *	"Analysis of a Simple Algorithm for Global Data Flow Problems",
6907dd7cddfSDavid du Colombier  *	Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
6917dd7cddfSDavid du Colombier  *	Oct. 1-3, 1973, pp.  207-217.
6927dd7cddfSDavid du Colombier  * 3) find all nodes with a predecessor dominated by the current node.
6937dd7cddfSDavid du Colombier  *	such a node is a loop head.
6947dd7cddfSDavid du Colombier  *	recursively, all preds with a greater rpo number are in the loop
6957dd7cddfSDavid du Colombier  */
6967dd7cddfSDavid du Colombier long
postorder(Reg * r,Reg ** rpo2r,long n)6977dd7cddfSDavid du Colombier postorder(Reg *r, Reg **rpo2r, long n)
6983e12c5d1SDavid du Colombier {
6993e12c5d1SDavid du Colombier 	Reg *r1;
7003e12c5d1SDavid du Colombier 
7017dd7cddfSDavid du Colombier 	r->rpo = 1;
7027dd7cddfSDavid du Colombier 	r1 = r->s1;
7037dd7cddfSDavid du Colombier 	if(r1 && !r1->rpo)
7047dd7cddfSDavid du Colombier 		n = postorder(r1, rpo2r, n);
7057dd7cddfSDavid du Colombier 	r1 = r->s2;
7067dd7cddfSDavid du Colombier 	if(r1 && !r1->rpo)
7077dd7cddfSDavid du Colombier 		n = postorder(r1, rpo2r, n);
7087dd7cddfSDavid du Colombier 	rpo2r[n] = r;
7097dd7cddfSDavid du Colombier 	n++;
7107dd7cddfSDavid du Colombier 	return n;
7113e12c5d1SDavid du Colombier }
7127dd7cddfSDavid du Colombier 
7137dd7cddfSDavid du Colombier long
rpolca(long * idom,long rpo1,long rpo2)7147dd7cddfSDavid du Colombier rpolca(long *idom, long rpo1, long rpo2)
7157dd7cddfSDavid du Colombier {
7167dd7cddfSDavid du Colombier 	long t;
7177dd7cddfSDavid du Colombier 
7187dd7cddfSDavid du Colombier 	if(rpo1 == -1)
7197dd7cddfSDavid du Colombier 		return rpo2;
7207dd7cddfSDavid du Colombier 	while(rpo1 != rpo2){
7217dd7cddfSDavid du Colombier 		if(rpo1 > rpo2){
7227dd7cddfSDavid du Colombier 			t = rpo2;
7237dd7cddfSDavid du Colombier 			rpo2 = rpo1;
7247dd7cddfSDavid du Colombier 			rpo1 = t;
7253e12c5d1SDavid du Colombier 		}
7267dd7cddfSDavid du Colombier 		while(rpo1 < rpo2){
7277dd7cddfSDavid du Colombier 			t = idom[rpo2];
7287dd7cddfSDavid du Colombier 			if(t >= rpo2)
729*375daca8SDavid du Colombier 				fatal(Z, "bad idom");
7307dd7cddfSDavid du Colombier 			rpo2 = t;
7317dd7cddfSDavid du Colombier 		}
7327dd7cddfSDavid du Colombier 	}
7337dd7cddfSDavid du Colombier 	return rpo1;
7347dd7cddfSDavid du Colombier }
7357dd7cddfSDavid du Colombier 
7367dd7cddfSDavid du Colombier int
doms(long * idom,long r,long s)7377dd7cddfSDavid du Colombier doms(long *idom, long r, long s)
7387dd7cddfSDavid du Colombier {
7397dd7cddfSDavid du Colombier 	while(s > r)
7407dd7cddfSDavid du Colombier 		s = idom[s];
7417dd7cddfSDavid du Colombier 	return s == r;
7427dd7cddfSDavid du Colombier }
7437dd7cddfSDavid du Colombier 
7447dd7cddfSDavid du Colombier int
loophead(long * idom,Reg * r)7457dd7cddfSDavid du Colombier loophead(long *idom, Reg *r)
7467dd7cddfSDavid du Colombier {
7477dd7cddfSDavid du Colombier 	long src;
7487dd7cddfSDavid du Colombier 
7497dd7cddfSDavid du Colombier 	src = r->rpo;
7507dd7cddfSDavid du Colombier 	if(r->p1 != R && doms(idom, src, r->p1->rpo))
7517dd7cddfSDavid du Colombier 		return 1;
7527dd7cddfSDavid du Colombier 	for(r = r->p2; r != R; r = r->p2link)
7537dd7cddfSDavid du Colombier 		if(doms(idom, src, r->rpo))
7547dd7cddfSDavid du Colombier 			return 1;
7557dd7cddfSDavid du Colombier 	return 0;
7567dd7cddfSDavid du Colombier }
7577dd7cddfSDavid du Colombier 
7587dd7cddfSDavid du Colombier void
loopmark(Reg ** rpo2r,long head,Reg * r)7597dd7cddfSDavid du Colombier loopmark(Reg **rpo2r, long head, Reg *r)
7607dd7cddfSDavid du Colombier {
7617dd7cddfSDavid du Colombier 	if(r->rpo < head || r->active == head)
7627dd7cddfSDavid du Colombier 		return;
7637dd7cddfSDavid du Colombier 	r->active = head;
7647dd7cddfSDavid du Colombier 	r->loop += LOOP;
7657dd7cddfSDavid du Colombier 	if(r->p1 != R)
7667dd7cddfSDavid du Colombier 		loopmark(rpo2r, head, r->p1);
7677dd7cddfSDavid du Colombier 	for(r = r->p2; r != R; r = r->p2link)
7687dd7cddfSDavid du Colombier 		loopmark(rpo2r, head, r);
7697dd7cddfSDavid du Colombier }
7707dd7cddfSDavid du Colombier 
7717dd7cddfSDavid du Colombier void
loopit(Reg * r,long nr)7727dd7cddfSDavid du Colombier loopit(Reg *r, long nr)
7737dd7cddfSDavid du Colombier {
77459cc4ca5SDavid du Colombier 	Reg *r1;
77559cc4ca5SDavid du Colombier 	long i, d, me;
7767dd7cddfSDavid du Colombier 
77759cc4ca5SDavid du Colombier 	if(nr > maxnr) {
77859cc4ca5SDavid du Colombier 		rpo2r = alloc(nr * sizeof(Reg*));
77959cc4ca5SDavid du Colombier 		idom = alloc(nr * sizeof(long));
78059cc4ca5SDavid du Colombier 		maxnr = nr;
78159cc4ca5SDavid du Colombier 	}
78259cc4ca5SDavid du Colombier 
7837dd7cddfSDavid du Colombier 	d = postorder(r, rpo2r, 0);
7847dd7cddfSDavid du Colombier 	if(d > nr)
785*375daca8SDavid du Colombier 		fatal(Z, "too many reg nodes");
7867dd7cddfSDavid du Colombier 	nr = d;
7877dd7cddfSDavid du Colombier 	for(i = 0; i < nr / 2; i++){
7887dd7cddfSDavid du Colombier 		r1 = rpo2r[i];
7897dd7cddfSDavid du Colombier 		rpo2r[i] = rpo2r[nr - 1 - i];
7907dd7cddfSDavid du Colombier 		rpo2r[nr - 1 - i] = r1;
7917dd7cddfSDavid du Colombier 	}
7927dd7cddfSDavid du Colombier 	for(i = 0; i < nr; i++)
7937dd7cddfSDavid du Colombier 		rpo2r[i]->rpo = i;
7947dd7cddfSDavid du Colombier 
7957dd7cddfSDavid du Colombier 	idom[0] = 0;
7967dd7cddfSDavid du Colombier 	for(i = 0; i < nr; i++){
7977dd7cddfSDavid du Colombier 		r1 = rpo2r[i];
7987dd7cddfSDavid du Colombier 		me = r1->rpo;
7997dd7cddfSDavid du Colombier 		d = -1;
8007dd7cddfSDavid du Colombier 		if(r1->p1 != R && r1->p1->rpo < me)
8017dd7cddfSDavid du Colombier 			d = r1->p1->rpo;
8027dd7cddfSDavid du Colombier 		for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
8037dd7cddfSDavid du Colombier 			if(r1->rpo < me)
8047dd7cddfSDavid du Colombier 				d = rpolca(idom, d, r1->rpo);
8057dd7cddfSDavid du Colombier 		idom[i] = d;
8067dd7cddfSDavid du Colombier 	}
8077dd7cddfSDavid du Colombier 
8087dd7cddfSDavid du Colombier 	for(i = 0; i < nr; i++){
8097dd7cddfSDavid du Colombier 		r1 = rpo2r[i];
8107dd7cddfSDavid du Colombier 		r1->loop++;
8117dd7cddfSDavid du Colombier 		if(r1->p2 != R && loophead(idom, r1))
8127dd7cddfSDavid du Colombier 			loopmark(rpo2r, i, r1);
8137dd7cddfSDavid du Colombier 	}
8143e12c5d1SDavid du Colombier }
8153e12c5d1SDavid du Colombier 
8163e12c5d1SDavid du Colombier void
synch(Reg * r,Bits dif)8173e12c5d1SDavid du Colombier synch(Reg *r, Bits dif)
8183e12c5d1SDavid du Colombier {
8193e12c5d1SDavid du Colombier 	Reg *r1;
8203e12c5d1SDavid du Colombier 	int z;
8213e12c5d1SDavid du Colombier 
8223e12c5d1SDavid du Colombier 	for(r1 = r; r1 != R; r1 = r1->s1) {
8233e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++) {
8243e12c5d1SDavid du Colombier 			dif.b[z] = (dif.b[z] &
8253e12c5d1SDavid du Colombier 				~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
8263e12c5d1SDavid du Colombier 					r1->set.b[z] | r1->regdiff.b[z];
8273e12c5d1SDavid du Colombier 			if(dif.b[z] != r1->regdiff.b[z]) {
8283e12c5d1SDavid du Colombier 				r1->regdiff.b[z] = dif.b[z];
8293e12c5d1SDavid du Colombier 				change++;
8303e12c5d1SDavid du Colombier 			}
8313e12c5d1SDavid du Colombier 		}
8323e12c5d1SDavid du Colombier 		if(r1->active)
8333e12c5d1SDavid du Colombier 			break;
8343e12c5d1SDavid du Colombier 		r1->active = 1;
8353e12c5d1SDavid du Colombier 		for(z=0; z<BITS; z++)
8363e12c5d1SDavid du Colombier 			dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
8373e12c5d1SDavid du Colombier 		if(r1->s2 != R)
8383e12c5d1SDavid du Colombier 			synch(r1->s2, dif);
8393e12c5d1SDavid du Colombier 	}
8403e12c5d1SDavid du Colombier }
8413e12c5d1SDavid du Colombier 
8423e12c5d1SDavid du Colombier ulong
allreg(ulong b,Rgn * r)8433e12c5d1SDavid du Colombier allreg(ulong b, Rgn *r)
8443e12c5d1SDavid du Colombier {
8453e12c5d1SDavid du Colombier 	Var *v;
8463e12c5d1SDavid du Colombier 	int i;
8473e12c5d1SDavid du Colombier 
8483e12c5d1SDavid du Colombier 	v = var + r->varno;
8493e12c5d1SDavid du Colombier 	r->regno = 0;
8503e12c5d1SDavid du Colombier 	switch(v->etype) {
8513e12c5d1SDavid du Colombier 
8523e12c5d1SDavid du Colombier 	default:
8533e12c5d1SDavid du Colombier 		diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
8543e12c5d1SDavid du Colombier 		break;
8553e12c5d1SDavid du Colombier 
8563e12c5d1SDavid du Colombier 	case TCHAR:
8573e12c5d1SDavid du Colombier 	case TUCHAR:
8583e12c5d1SDavid du Colombier 	case TSHORT:
8593e12c5d1SDavid du Colombier 	case TUSHORT:
8607dd7cddfSDavid du Colombier 	case TINT:
8617dd7cddfSDavid du Colombier 	case TUINT:
8623e12c5d1SDavid du Colombier 	case TLONG:
8633e12c5d1SDavid du Colombier 	case TULONG:
8643e12c5d1SDavid du Colombier 	case TIND:
8653e12c5d1SDavid du Colombier 	case TARRAY:
8663e12c5d1SDavid du Colombier 		i = BtoR(~b);
867219b2ee8SDavid du Colombier 		if(i && r->cost >= 0) {
8683e12c5d1SDavid du Colombier 			r->regno = i;
8693e12c5d1SDavid du Colombier 			return RtoB(i);
8703e12c5d1SDavid du Colombier 		}
8713e12c5d1SDavid du Colombier 		break;
8723e12c5d1SDavid du Colombier 
8733e12c5d1SDavid du Colombier 	case TDOUBLE:
8743e12c5d1SDavid du Colombier 	case TFLOAT:
8753e12c5d1SDavid du Colombier 		i = BtoF(~b);
876219b2ee8SDavid du Colombier 		if(i && r->cost >= 0) {
8773e12c5d1SDavid du Colombier 			r->regno = i+NREG;
8783e12c5d1SDavid du Colombier 			return FtoB(i);
8793e12c5d1SDavid du Colombier 		}
8803e12c5d1SDavid du Colombier 		break;
8813e12c5d1SDavid du Colombier 	}
8823e12c5d1SDavid du Colombier 	return 0;
8833e12c5d1SDavid du Colombier }
8843e12c5d1SDavid du Colombier 
8853e12c5d1SDavid du Colombier void
paint1(Reg * r,int bn)8863e12c5d1SDavid du Colombier paint1(Reg *r, int bn)
8873e12c5d1SDavid du Colombier {
8883e12c5d1SDavid du Colombier 	Reg *r1;
8893e12c5d1SDavid du Colombier 	Prog *p;
8903e12c5d1SDavid du Colombier 	int z;
8913e12c5d1SDavid du Colombier 	ulong bb;
8923e12c5d1SDavid du Colombier 
8933e12c5d1SDavid du Colombier 	z = bn/32;
8943e12c5d1SDavid du Colombier 	bb = 1L<<(bn%32);
8953e12c5d1SDavid du Colombier 	if(r->act.b[z] & bb)
8963e12c5d1SDavid du Colombier 		return;
8973e12c5d1SDavid du Colombier 	for(;;) {
8983e12c5d1SDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
8993e12c5d1SDavid du Colombier 			break;
9003e12c5d1SDavid du Colombier 		r1 = r->p1;
9013e12c5d1SDavid du Colombier 		if(r1 == R)
9023e12c5d1SDavid du Colombier 			break;
9033e12c5d1SDavid du Colombier 		if(!(r1->refahead.b[z] & bb))
9043e12c5d1SDavid du Colombier 			break;
9053e12c5d1SDavid du Colombier 		if(r1->act.b[z] & bb)
9063e12c5d1SDavid du Colombier 			break;
9073e12c5d1SDavid du Colombier 		r = r1;
9083e12c5d1SDavid du Colombier 	}
9093e12c5d1SDavid du Colombier 
9103e12c5d1SDavid du Colombier 	if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) {
9113e12c5d1SDavid du Colombier 		change -= CLOAD * r->loop;
9123e12c5d1SDavid du Colombier 		if(debug['R'] && debug['v'])
9139a747e4fSDavid du Colombier 			print("%ld%P\tld %B $%d\n", r->loop,
9149a747e4fSDavid du Colombier 				r->prog, blsh(bn), change);
9153e12c5d1SDavid du Colombier 	}
9163e12c5d1SDavid du Colombier 	for(;;) {
9173e12c5d1SDavid du Colombier 		r->act.b[z] |= bb;
9183e12c5d1SDavid du Colombier 		p = r->prog;
9193e12c5d1SDavid du Colombier 
9203e12c5d1SDavid du Colombier 		if(r->use1.b[z] & bb) {
9213e12c5d1SDavid du Colombier 			change += CREF * r->loop;
9223e12c5d1SDavid du Colombier 			if(debug['R'] && debug['v'])
9239a747e4fSDavid du Colombier 				print("%ld%P\tu1 %B $%d\n", r->loop,
9249a747e4fSDavid du Colombier 					p, blsh(bn), change);
9253e12c5d1SDavid du Colombier 		}
9263e12c5d1SDavid du Colombier 
9273e12c5d1SDavid du Colombier 		if((r->use2.b[z]|r->set.b[z]) & bb) {
9283e12c5d1SDavid du Colombier 			change += CREF * r->loop;
9293e12c5d1SDavid du Colombier 			if(debug['R'] && debug['v'])
9309a747e4fSDavid du Colombier 				print("%ld%P\tu2 %B $%d\n", r->loop,
9319a747e4fSDavid du Colombier 					p, blsh(bn), change);
9323e12c5d1SDavid du Colombier 		}
9333e12c5d1SDavid du Colombier 
9343e12c5d1SDavid du Colombier 		if(STORE(r) & r->regdiff.b[z] & bb) {
9353e12c5d1SDavid du Colombier 			change -= CLOAD * r->loop;
9363e12c5d1SDavid du Colombier 			if(debug['R'] && debug['v'])
9379a747e4fSDavid du Colombier 				print("%ld%P\tst %B $%d\n", r->loop,
9389a747e4fSDavid du Colombier 					p, blsh(bn), change);
9393e12c5d1SDavid du Colombier 		}
9403e12c5d1SDavid du Colombier 
9413e12c5d1SDavid du Colombier 		if(r->refbehind.b[z] & bb)
9423e12c5d1SDavid du Colombier 			for(r1 = r->p2; r1 != R; r1 = r1->p2link)
9433e12c5d1SDavid du Colombier 				if(r1->refahead.b[z] & bb)
9443e12c5d1SDavid du Colombier 					paint1(r1, bn);
9453e12c5d1SDavid du Colombier 
9463e12c5d1SDavid du Colombier 		if(!(r->refahead.b[z] & bb))
9473e12c5d1SDavid du Colombier 			break;
9483e12c5d1SDavid du Colombier 		r1 = r->s2;
9493e12c5d1SDavid du Colombier 		if(r1 != R)
9503e12c5d1SDavid du Colombier 			if(r1->refbehind.b[z] & bb)
9513e12c5d1SDavid du Colombier 				paint1(r1, bn);
9523e12c5d1SDavid du Colombier 		r = r->s1;
9533e12c5d1SDavid du Colombier 		if(r == R)
9543e12c5d1SDavid du Colombier 			break;
9553e12c5d1SDavid du Colombier 		if(r->act.b[z] & bb)
9563e12c5d1SDavid du Colombier 			break;
9573e12c5d1SDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
9583e12c5d1SDavid du Colombier 			break;
9593e12c5d1SDavid du Colombier 	}
9603e12c5d1SDavid du Colombier }
9613e12c5d1SDavid du Colombier 
9623e12c5d1SDavid du Colombier ulong
paint2(Reg * r,int bn)9633e12c5d1SDavid du Colombier paint2(Reg *r, int bn)
9643e12c5d1SDavid du Colombier {
9653e12c5d1SDavid du Colombier 	Reg *r1;
9663e12c5d1SDavid du Colombier 	int z;
9673e12c5d1SDavid du Colombier 	ulong bb, vreg;
9683e12c5d1SDavid du Colombier 
9693e12c5d1SDavid du Colombier 	z = bn/32;
9703e12c5d1SDavid du Colombier 	bb = 1L << (bn%32);
9713e12c5d1SDavid du Colombier 	vreg = regbits;
9723e12c5d1SDavid du Colombier 	if(!(r->act.b[z] & bb))
9733e12c5d1SDavid du Colombier 		return vreg;
9743e12c5d1SDavid du Colombier 	for(;;) {
9753e12c5d1SDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
9763e12c5d1SDavid du Colombier 			break;
9773e12c5d1SDavid du Colombier 		r1 = r->p1;
9783e12c5d1SDavid du Colombier 		if(r1 == R)
9793e12c5d1SDavid du Colombier 			break;
9803e12c5d1SDavid du Colombier 		if(!(r1->refahead.b[z] & bb))
9813e12c5d1SDavid du Colombier 			break;
9823e12c5d1SDavid du Colombier 		if(!(r1->act.b[z] & bb))
9833e12c5d1SDavid du Colombier 			break;
9843e12c5d1SDavid du Colombier 		r = r1;
9853e12c5d1SDavid du Colombier 	}
9863e12c5d1SDavid du Colombier 	for(;;) {
9873e12c5d1SDavid du Colombier 		r->act.b[z] &= ~bb;
9883e12c5d1SDavid du Colombier 
9893e12c5d1SDavid du Colombier 		vreg |= r->regu;
9903e12c5d1SDavid du Colombier 
9913e12c5d1SDavid du Colombier 		if(r->refbehind.b[z] & bb)
9923e12c5d1SDavid du Colombier 			for(r1 = r->p2; r1 != R; r1 = r1->p2link)
9933e12c5d1SDavid du Colombier 				if(r1->refahead.b[z] & bb)
9943e12c5d1SDavid du Colombier 					vreg |= paint2(r1, bn);
9953e12c5d1SDavid du Colombier 
9963e12c5d1SDavid du Colombier 		if(!(r->refahead.b[z] & bb))
9973e12c5d1SDavid du Colombier 			break;
9983e12c5d1SDavid du Colombier 		r1 = r->s2;
9993e12c5d1SDavid du Colombier 		if(r1 != R)
10003e12c5d1SDavid du Colombier 			if(r1->refbehind.b[z] & bb)
10013e12c5d1SDavid du Colombier 				vreg |= paint2(r1, bn);
10023e12c5d1SDavid du Colombier 		r = r->s1;
10033e12c5d1SDavid du Colombier 		if(r == R)
10043e12c5d1SDavid du Colombier 			break;
10053e12c5d1SDavid du Colombier 		if(!(r->act.b[z] & bb))
10063e12c5d1SDavid du Colombier 			break;
10073e12c5d1SDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
10083e12c5d1SDavid du Colombier 			break;
10093e12c5d1SDavid du Colombier 	}
10103e12c5d1SDavid du Colombier 	return vreg;
10113e12c5d1SDavid du Colombier }
10123e12c5d1SDavid du Colombier 
10133e12c5d1SDavid du Colombier void
paint3(Reg * r,int bn,long rb,int rn)10143e12c5d1SDavid du Colombier paint3(Reg *r, int bn, long rb, int rn)
10153e12c5d1SDavid du Colombier {
10163e12c5d1SDavid du Colombier 	Reg *r1;
10173e12c5d1SDavid du Colombier 	Prog *p;
10183e12c5d1SDavid du Colombier 	int z;
10193e12c5d1SDavid du Colombier 	ulong bb;
10203e12c5d1SDavid du Colombier 
10213e12c5d1SDavid du Colombier 	z = bn/32;
10223e12c5d1SDavid du Colombier 	bb = 1L << (bn%32);
10233e12c5d1SDavid du Colombier 	if(r->act.b[z] & bb)
10243e12c5d1SDavid du Colombier 		return;
10253e12c5d1SDavid du Colombier 	for(;;) {
10263e12c5d1SDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
10273e12c5d1SDavid du Colombier 			break;
10283e12c5d1SDavid du Colombier 		r1 = r->p1;
10293e12c5d1SDavid du Colombier 		if(r1 == R)
10303e12c5d1SDavid du Colombier 			break;
10313e12c5d1SDavid du Colombier 		if(!(r1->refahead.b[z] & bb))
10323e12c5d1SDavid du Colombier 			break;
10333e12c5d1SDavid du Colombier 		if(r1->act.b[z] & bb)
10343e12c5d1SDavid du Colombier 			break;
10353e12c5d1SDavid du Colombier 		r = r1;
10363e12c5d1SDavid du Colombier 	}
10373e12c5d1SDavid du Colombier 
10383e12c5d1SDavid du Colombier 	if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
10393e12c5d1SDavid du Colombier 		addmove(r, bn, rn, 0);
10403e12c5d1SDavid du Colombier 	for(;;) {
10413e12c5d1SDavid du Colombier 		r->act.b[z] |= bb;
10423e12c5d1SDavid du Colombier 		p = r->prog;
10433e12c5d1SDavid du Colombier 
10443e12c5d1SDavid du Colombier 		if(r->use1.b[z] & bb) {
10453e12c5d1SDavid du Colombier 			if(debug['R'])
10463e12c5d1SDavid du Colombier 				print("%P", p);
10473e12c5d1SDavid du Colombier 			addreg(&p->from, rn);
10483e12c5d1SDavid du Colombier 			if(debug['R'])
10499a747e4fSDavid du Colombier 				print("\t.c%P\n", p);
10503e12c5d1SDavid du Colombier 		}
10513e12c5d1SDavid du Colombier 		if((r->use2.b[z]|r->set.b[z]) & bb) {
10523e12c5d1SDavid du Colombier 			if(debug['R'])
10533e12c5d1SDavid du Colombier 				print("%P", p);
10543e12c5d1SDavid du Colombier 			addreg(&p->to, rn);
10553e12c5d1SDavid du Colombier 			if(debug['R'])
10569a747e4fSDavid du Colombier 				print("\t.c%P\n", p);
10573e12c5d1SDavid du Colombier 		}
10583e12c5d1SDavid du Colombier 
10593e12c5d1SDavid du Colombier 		if(STORE(r) & r->regdiff.b[z] & bb)
10603e12c5d1SDavid du Colombier 			addmove(r, bn, rn, 1);
10613e12c5d1SDavid du Colombier 		r->regu |= rb;
10623e12c5d1SDavid du Colombier 
10633e12c5d1SDavid du Colombier 		if(r->refbehind.b[z] & bb)
10643e12c5d1SDavid du Colombier 			for(r1 = r->p2; r1 != R; r1 = r1->p2link)
10653e12c5d1SDavid du Colombier 				if(r1->refahead.b[z] & bb)
10663e12c5d1SDavid du Colombier 					paint3(r1, bn, rb, rn);
10673e12c5d1SDavid du Colombier 
10683e12c5d1SDavid du Colombier 		if(!(r->refahead.b[z] & bb))
10693e12c5d1SDavid du Colombier 			break;
10703e12c5d1SDavid du Colombier 		r1 = r->s2;
10713e12c5d1SDavid du Colombier 		if(r1 != R)
10723e12c5d1SDavid du Colombier 			if(r1->refbehind.b[z] & bb)
10733e12c5d1SDavid du Colombier 				paint3(r1, bn, rb, rn);
10743e12c5d1SDavid du Colombier 		r = r->s1;
10753e12c5d1SDavid du Colombier 		if(r == R)
10763e12c5d1SDavid du Colombier 			break;
10773e12c5d1SDavid du Colombier 		if(r->act.b[z] & bb)
10783e12c5d1SDavid du Colombier 			break;
10793e12c5d1SDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
10803e12c5d1SDavid du Colombier 			break;
10813e12c5d1SDavid du Colombier 	}
10823e12c5d1SDavid du Colombier }
10833e12c5d1SDavid du Colombier 
10843e12c5d1SDavid du Colombier void
addreg(Adr * a,int rn)10853e12c5d1SDavid du Colombier addreg(Adr *a, int rn)
10863e12c5d1SDavid du Colombier {
10873e12c5d1SDavid du Colombier 
10883e12c5d1SDavid du Colombier 	a->sym = 0;
10893e12c5d1SDavid du Colombier 	a->name = D_NONE;
10903e12c5d1SDavid du Colombier 	a->type = D_REG;
10913e12c5d1SDavid du Colombier 	a->reg = rn;
10923e12c5d1SDavid du Colombier 	if(rn >= NREG) {
10933e12c5d1SDavid du Colombier 		a->type = D_FREG;
10943e12c5d1SDavid du Colombier 		a->reg = rn-NREG;
10953e12c5d1SDavid du Colombier 	}
10963e12c5d1SDavid du Colombier }
10973e12c5d1SDavid du Colombier 
10983e12c5d1SDavid du Colombier /*
10993e12c5d1SDavid du Colombier  *	bit	reg
11003e12c5d1SDavid du Colombier  *	0	R3
11013e12c5d1SDavid du Colombier  *	1	R4
11023e12c5d1SDavid du Colombier  *	...	...
11033e12c5d1SDavid du Colombier  *	19	R22
11043e12c5d1SDavid du Colombier  *	20	R23
11053e12c5d1SDavid du Colombier  */
11063e12c5d1SDavid du Colombier long
RtoB(int r)11073e12c5d1SDavid du Colombier RtoB(int r)
11083e12c5d1SDavid du Colombier {
11093e12c5d1SDavid du Colombier 
11103e12c5d1SDavid du Colombier 	if(r < 3 || r > 23)
11113e12c5d1SDavid du Colombier 		return 0;
11123e12c5d1SDavid du Colombier 	return 1L << (r-3);
11133e12c5d1SDavid du Colombier }
11143e12c5d1SDavid du Colombier 
BtoR(long b)11153e12c5d1SDavid du Colombier BtoR(long b)
11163e12c5d1SDavid du Colombier {
11173e12c5d1SDavid du Colombier 
11183e12c5d1SDavid du Colombier 	b &= 0x001fffffL;
11193e12c5d1SDavid du Colombier 	if(b == 0)
11203e12c5d1SDavid du Colombier 		return 0;
11213e12c5d1SDavid du Colombier 	return bitno(b) + 3;
11223e12c5d1SDavid du Colombier }
11233e12c5d1SDavid du Colombier 
11243e12c5d1SDavid du Colombier /*
11253e12c5d1SDavid du Colombier  *	bit	reg
11263e12c5d1SDavid du Colombier  *	22	F4
11273e12c5d1SDavid du Colombier  *	23	F6
11283e12c5d1SDavid du Colombier  *	...	...
11293e12c5d1SDavid du Colombier  *	31	F22
11303e12c5d1SDavid du Colombier  */
11313e12c5d1SDavid du Colombier long
FtoB(int f)11323e12c5d1SDavid du Colombier FtoB(int f)
11333e12c5d1SDavid du Colombier {
11343e12c5d1SDavid du Colombier 
11353e12c5d1SDavid du Colombier 	if(f < 4 || f > 22 || (f&1))
11363e12c5d1SDavid du Colombier 		return 0;
11373e12c5d1SDavid du Colombier 	return 1L << (f/2 + 20);
11383e12c5d1SDavid du Colombier }
11393e12c5d1SDavid du Colombier 
1140219b2ee8SDavid du Colombier int
BtoF(long b)11413e12c5d1SDavid du Colombier BtoF(long b)
11423e12c5d1SDavid du Colombier {
11433e12c5d1SDavid du Colombier 
11443e12c5d1SDavid du Colombier 	b &= 0xffc00000L;
11453e12c5d1SDavid du Colombier 	if(b == 0)
11463e12c5d1SDavid du Colombier 		return 0;
11473e12c5d1SDavid du Colombier 	return bitno(b)*2 - 40;
11483e12c5d1SDavid du Colombier }
1149