xref: /plan9/sys/src/cmd/qc/reg.c (revision 6891d8578618fb7ccda4a131c122d4d0e6580c4b)
17dd7cddfSDavid du Colombier #include "gc.h"
27dd7cddfSDavid du Colombier 
37dd7cddfSDavid du Colombier Reg*
rega(void)47dd7cddfSDavid du Colombier rega(void)
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier 	Reg *r;
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier 	r = freer;
97dd7cddfSDavid du Colombier 	if(r == R) {
107dd7cddfSDavid du Colombier 		r = alloc(sizeof(*r));
117dd7cddfSDavid du Colombier 	} else
127dd7cddfSDavid du Colombier 		freer = r->link;
137dd7cddfSDavid du Colombier 
147dd7cddfSDavid du Colombier 	*r = zreg;
157dd7cddfSDavid du Colombier 	return r;
167dd7cddfSDavid du Colombier }
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier int
rcmp(void * a1,void * a2)197dd7cddfSDavid du Colombier rcmp(void *a1, void *a2)
207dd7cddfSDavid du Colombier {
217dd7cddfSDavid du Colombier 	Rgn *p1, *p2;
227dd7cddfSDavid du Colombier 	int c1, c2;
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier 	p1 = a1;
257dd7cddfSDavid du Colombier 	p2 = a2;
267dd7cddfSDavid du Colombier 	c1 = p2->cost;
277dd7cddfSDavid du Colombier 	c2 = p1->cost;
287dd7cddfSDavid du Colombier 	if(c1 -= c2)
297dd7cddfSDavid du Colombier 		return c1;
307dd7cddfSDavid du Colombier 	return p2->varno - p1->varno;
317dd7cddfSDavid du Colombier }
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier void
regopt(Prog * p)347dd7cddfSDavid du Colombier regopt(Prog *p)
357dd7cddfSDavid du Colombier {
367dd7cddfSDavid du Colombier 	Reg *r, *r1, *r2;
377dd7cddfSDavid du Colombier 	Prog *p1;
387dd7cddfSDavid du Colombier 	int i, z;
397dd7cddfSDavid du Colombier 	long initpc, val, npc;
407dd7cddfSDavid du Colombier 	ulong vreg;
417dd7cddfSDavid du Colombier 	Bits bit;
427dd7cddfSDavid du Colombier 	struct
437dd7cddfSDavid du Colombier 	{
447dd7cddfSDavid du Colombier 		long	m;
457dd7cddfSDavid du Colombier 		long	c;
467dd7cddfSDavid du Colombier 		Reg*	p;
477dd7cddfSDavid du Colombier 	} log5[6], *lp;
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier 	firstr = R;
507dd7cddfSDavid du Colombier 	lastr = R;
517dd7cddfSDavid du Colombier 	nvar = 0;
527dd7cddfSDavid du Colombier 	regbits = 0;
537dd7cddfSDavid du Colombier 	for(z=0; z<BITS; z++) {
547dd7cddfSDavid du Colombier 		externs.b[z] = 0;
557dd7cddfSDavid du Colombier 		params.b[z] = 0;
567dd7cddfSDavid du Colombier 		consts.b[z] = 0;
577dd7cddfSDavid du Colombier 		addrs.b[z] = 0;
587dd7cddfSDavid du Colombier 	}
597dd7cddfSDavid du Colombier 
607dd7cddfSDavid du Colombier 	/*
617dd7cddfSDavid du Colombier 	 * pass 1
627dd7cddfSDavid du Colombier 	 * build aux data structure
637dd7cddfSDavid du Colombier 	 * allocate pcs
647dd7cddfSDavid du Colombier 	 * find use and set of variables
657dd7cddfSDavid du Colombier 	 */
667dd7cddfSDavid du Colombier 	val = 5L * 5L * 5L * 5L * 5L;
677dd7cddfSDavid du Colombier 	lp = log5;
687dd7cddfSDavid du Colombier 	for(i=0; i<5; i++) {
697dd7cddfSDavid du Colombier 		lp->m = val;
707dd7cddfSDavid du Colombier 		lp->c = 0;
717dd7cddfSDavid du Colombier 		lp->p = R;
727dd7cddfSDavid du Colombier 		val /= 5L;
737dd7cddfSDavid du Colombier 		lp++;
747dd7cddfSDavid du Colombier 	}
757dd7cddfSDavid du Colombier 	val = 0;
767dd7cddfSDavid du Colombier 	for(; p != P; p = p->link) {
777dd7cddfSDavid du Colombier 		switch(p->as) {
787dd7cddfSDavid du Colombier 		case ADATA:
797dd7cddfSDavid du Colombier 		case AGLOBL:
807dd7cddfSDavid du Colombier 		case ANAME:
81*375daca8SDavid du Colombier 		case ASIGNAME:
827dd7cddfSDavid du Colombier 			continue;
837dd7cddfSDavid du Colombier 		}
847dd7cddfSDavid du Colombier 		r = rega();
857dd7cddfSDavid du Colombier 		if(firstr == R) {
867dd7cddfSDavid du Colombier 			firstr = r;
877dd7cddfSDavid du Colombier 			lastr = r;
887dd7cddfSDavid du Colombier 		} else {
897dd7cddfSDavid du Colombier 			lastr->link = r;
907dd7cddfSDavid du Colombier 			r->p1 = lastr;
917dd7cddfSDavid du Colombier 			lastr->s1 = r;
927dd7cddfSDavid du Colombier 			lastr = r;
937dd7cddfSDavid du Colombier 		}
947dd7cddfSDavid du Colombier 		r->prog = p;
957dd7cddfSDavid du Colombier 		r->pc = val;
967dd7cddfSDavid du Colombier 		val++;
977dd7cddfSDavid du Colombier 
987dd7cddfSDavid du Colombier 		lp = log5;
997dd7cddfSDavid du Colombier 		for(i=0; i<5; i++) {
1007dd7cddfSDavid du Colombier 			lp->c--;
1017dd7cddfSDavid du Colombier 			if(lp->c <= 0) {
1027dd7cddfSDavid du Colombier 				lp->c = lp->m;
1037dd7cddfSDavid du Colombier 				if(lp->p != R)
1047dd7cddfSDavid du Colombier 					lp->p->log5 = r;
1057dd7cddfSDavid du Colombier 				lp->p = r;
1067dd7cddfSDavid du Colombier 				(lp+1)->c = 0;
1077dd7cddfSDavid du Colombier 				break;
1087dd7cddfSDavid du Colombier 			}
1097dd7cddfSDavid du Colombier 			lp++;
1107dd7cddfSDavid du Colombier 		}
1117dd7cddfSDavid du Colombier 
1127dd7cddfSDavid du Colombier 		r1 = r->p1;
1137dd7cddfSDavid du Colombier 		if(r1 != R)
1147dd7cddfSDavid du Colombier 		switch(r1->prog->as) {
1157dd7cddfSDavid du Colombier 		case ARETURN:
1167dd7cddfSDavid du Colombier 		case ABR:
1177dd7cddfSDavid du Colombier 		case ARFI:
1187dd7cddfSDavid du Colombier 			r->p1 = R;
1197dd7cddfSDavid du Colombier 			r1->s1 = R;
1207dd7cddfSDavid du Colombier 		}
1217dd7cddfSDavid du Colombier 
1227dd7cddfSDavid du Colombier 		/*
1237dd7cddfSDavid du Colombier 		 * left side always read
1247dd7cddfSDavid du Colombier 		 */
1257dd7cddfSDavid du Colombier 		bit = mkvar(&p->from, p->as==AMOVW);
1267dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
1277dd7cddfSDavid du Colombier 			r->use1.b[z] |= bit.b[z];
1287dd7cddfSDavid du Colombier 
1297dd7cddfSDavid du Colombier 		/*
1307dd7cddfSDavid du Colombier 		 * right side depends on opcode
1317dd7cddfSDavid du Colombier 		 */
1327dd7cddfSDavid du Colombier 		bit = mkvar(&p->to, 0);
1337dd7cddfSDavid du Colombier 		if(bany(&bit))
1347dd7cddfSDavid du Colombier 		switch(p->as) {
1357dd7cddfSDavid du Colombier 		default:
1367dd7cddfSDavid du Colombier 			diag(Z, "reg: unknown asop: %A", p->as);
1377dd7cddfSDavid du Colombier 			break;
1387dd7cddfSDavid du Colombier 
1397dd7cddfSDavid du Colombier 		/*
1407dd7cddfSDavid du Colombier 		 * right side write
1417dd7cddfSDavid du Colombier 		 */
1427dd7cddfSDavid du Colombier 		case ANOP:
1437dd7cddfSDavid du Colombier 		case AMOVB:
1447dd7cddfSDavid du Colombier 		case AMOVBU:
1457dd7cddfSDavid du Colombier 		case AMOVBZ:
1467dd7cddfSDavid du Colombier 		case AMOVBZU:
1477dd7cddfSDavid du Colombier 		case AMOVH:
1487dd7cddfSDavid du Colombier 		case AMOVHBR:
1497dd7cddfSDavid du Colombier 		case AMOVHU:
1507dd7cddfSDavid du Colombier 		case AMOVHZ:
1517dd7cddfSDavid du Colombier 		case AMOVHZU:
1527dd7cddfSDavid du Colombier 		case AMOVW:
1537dd7cddfSDavid du Colombier 		case AMOVWU:
1547dd7cddfSDavid du Colombier 		case AFMOVD:
1557dd7cddfSDavid du Colombier 		case AFMOVDCC:
1567dd7cddfSDavid du Colombier 		case AFMOVDU:
1577dd7cddfSDavid du Colombier 		case AFMOVS:
1587dd7cddfSDavid du Colombier 		case AFMOVSU:
1597dd7cddfSDavid du Colombier 		case AFRSP:
1607dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++)
1617dd7cddfSDavid du Colombier 				r->set.b[z] |= bit.b[z];
1627dd7cddfSDavid du Colombier 			break;
1637dd7cddfSDavid du Colombier 
1647dd7cddfSDavid du Colombier 		/*
1657dd7cddfSDavid du Colombier 		 * funny
1667dd7cddfSDavid du Colombier 		 */
1677dd7cddfSDavid du Colombier 		case ABL:
1687dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++)
1697dd7cddfSDavid du Colombier 				addrs.b[z] |= bit.b[z];
1707dd7cddfSDavid du Colombier 			break;
1717dd7cddfSDavid du Colombier 		}
1727dd7cddfSDavid du Colombier 	}
1737dd7cddfSDavid du Colombier 	if(firstr == R)
1747dd7cddfSDavid du Colombier 		return;
1757dd7cddfSDavid du Colombier 	initpc = pc - val;
1767dd7cddfSDavid du Colombier 	npc = val;
1777dd7cddfSDavid du Colombier 
1787dd7cddfSDavid du Colombier 	/*
1797dd7cddfSDavid du Colombier 	 * pass 2
1807dd7cddfSDavid du Colombier 	 * turn branch references to pointers
1817dd7cddfSDavid du Colombier 	 * build back pointers
1827dd7cddfSDavid du Colombier 	 */
1837dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
1847dd7cddfSDavid du Colombier 		p = r->prog;
1857dd7cddfSDavid du Colombier 		if(p->to.type == D_BRANCH) {
1867dd7cddfSDavid du Colombier 			val = p->to.offset - initpc;
1877dd7cddfSDavid du Colombier 			r1 = firstr;
1887dd7cddfSDavid du Colombier 			while(r1 != R) {
1897dd7cddfSDavid du Colombier 				r2 = r1->log5;
1907dd7cddfSDavid du Colombier 				if(r2 != R && val >= r2->pc) {
1917dd7cddfSDavid du Colombier 					r1 = r2;
1927dd7cddfSDavid du Colombier 					continue;
1937dd7cddfSDavid du Colombier 				}
1947dd7cddfSDavid du Colombier 				if(r1->pc == val)
1957dd7cddfSDavid du Colombier 					break;
1967dd7cddfSDavid du Colombier 				r1 = r1->link;
1977dd7cddfSDavid du Colombier 			}
1987dd7cddfSDavid du Colombier 			if(r1 == R) {
1997dd7cddfSDavid du Colombier 				nearln = p->lineno;
2007dd7cddfSDavid du Colombier 				diag(Z, "ref not found\n%P", p);
2017dd7cddfSDavid du Colombier 				continue;
2027dd7cddfSDavid du Colombier 			}
2037dd7cddfSDavid du Colombier 			if(r1 == r) {
2047dd7cddfSDavid du Colombier 				nearln = p->lineno;
2057dd7cddfSDavid du Colombier 				diag(Z, "ref to self\n%P", p);
2067dd7cddfSDavid du Colombier 				continue;
2077dd7cddfSDavid du Colombier 			}
2087dd7cddfSDavid du Colombier 			r->s2 = r1;
2097dd7cddfSDavid du Colombier 			r->p2link = r1->p2;
2107dd7cddfSDavid du Colombier 			r1->p2 = r;
2117dd7cddfSDavid du Colombier 		}
2127dd7cddfSDavid du Colombier 	}
2137dd7cddfSDavid du Colombier 	if(debug['R']) {
2147dd7cddfSDavid du Colombier 		p = firstr->prog;
2157dd7cddfSDavid du Colombier 		print("\n%L %D\n", p->lineno, &p->from);
2167dd7cddfSDavid du Colombier 	}
2177dd7cddfSDavid du Colombier 
2187dd7cddfSDavid du Colombier 	/*
2197dd7cddfSDavid du Colombier 	 * pass 2.5
2207dd7cddfSDavid du Colombier 	 * find looping structure
2217dd7cddfSDavid du Colombier 	 */
2227dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2237dd7cddfSDavid du Colombier 		r->active = 0;
2247dd7cddfSDavid du Colombier 	change = 0;
2257dd7cddfSDavid du Colombier 	loopit(firstr, npc);
2267dd7cddfSDavid du Colombier 	if(debug['R'] && debug['v']) {
2277dd7cddfSDavid du Colombier 		print("\nlooping structure:\n");
2287dd7cddfSDavid du Colombier 		for(r = firstr; r != R; r = r->link) {
2297dd7cddfSDavid du Colombier 			print("%ld:%P", r->loop, r->prog);
2307dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++)
2317dd7cddfSDavid du Colombier 				bit.b[z] = r->use1.b[z] |
2327dd7cddfSDavid du Colombier 					r->use2.b[z] | r->set.b[z];
2337dd7cddfSDavid du Colombier 			if(bany(&bit)) {
2349a747e4fSDavid du Colombier 				print("\t");
2357dd7cddfSDavid du Colombier 				if(bany(&r->use1))
2367dd7cddfSDavid du Colombier 					print(" u1=%B", r->use1);
2377dd7cddfSDavid du Colombier 				if(bany(&r->use2))
2387dd7cddfSDavid du Colombier 					print(" u2=%B", r->use2);
2397dd7cddfSDavid du Colombier 				if(bany(&r->set))
2407dd7cddfSDavid du Colombier 					print(" st=%B", r->set);
2417dd7cddfSDavid du Colombier 			}
2427dd7cddfSDavid du Colombier 			print("\n");
2437dd7cddfSDavid du Colombier 		}
2447dd7cddfSDavid du Colombier 	}
2457dd7cddfSDavid du Colombier 
2467dd7cddfSDavid du Colombier 	/*
2477dd7cddfSDavid du Colombier 	 * pass 3
2487dd7cddfSDavid du Colombier 	 * iterate propagating usage
2497dd7cddfSDavid du Colombier 	 * 	back until flow graph is complete
2507dd7cddfSDavid du Colombier 	 */
2517dd7cddfSDavid du Colombier loop1:
2527dd7cddfSDavid du Colombier 	change = 0;
2537dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2547dd7cddfSDavid du Colombier 		r->active = 0;
2557dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2567dd7cddfSDavid du Colombier 		if(r->prog->as == ARETURN)
2577dd7cddfSDavid du Colombier 			prop(r, zbits, zbits);
2587dd7cddfSDavid du Colombier loop11:
2597dd7cddfSDavid du Colombier 	/* pick up unreachable code */
2607dd7cddfSDavid du Colombier 	i = 0;
2617dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r1) {
2627dd7cddfSDavid du Colombier 		r1 = r->link;
2637dd7cddfSDavid du Colombier 		if(r1 && r1->active && !r->active) {
2647dd7cddfSDavid du Colombier 			prop(r, zbits, zbits);
2657dd7cddfSDavid du Colombier 			i = 1;
2667dd7cddfSDavid du Colombier 		}
2677dd7cddfSDavid du Colombier 	}
2687dd7cddfSDavid du Colombier 	if(i)
2697dd7cddfSDavid du Colombier 		goto loop11;
2707dd7cddfSDavid du Colombier 	if(change)
2717dd7cddfSDavid du Colombier 		goto loop1;
2727dd7cddfSDavid du Colombier 
2737dd7cddfSDavid du Colombier 
2747dd7cddfSDavid du Colombier 	/*
2757dd7cddfSDavid du Colombier 	 * pass 4
2767dd7cddfSDavid du Colombier 	 * iterate propagating register/variable synchrony
2777dd7cddfSDavid du Colombier 	 * 	forward until graph is complete
2787dd7cddfSDavid du Colombier 	 */
2797dd7cddfSDavid du Colombier loop2:
2807dd7cddfSDavid du Colombier 	change = 0;
2817dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link)
2827dd7cddfSDavid du Colombier 		r->active = 0;
2837dd7cddfSDavid du Colombier 	synch(firstr, zbits);
2847dd7cddfSDavid du Colombier 	if(change)
2857dd7cddfSDavid du Colombier 		goto loop2;
2867dd7cddfSDavid du Colombier 
2877dd7cddfSDavid du Colombier 
2887dd7cddfSDavid du Colombier 	/*
2897dd7cddfSDavid du Colombier 	 * pass 5
2907dd7cddfSDavid du Colombier 	 * isolate regions
2917dd7cddfSDavid du Colombier 	 * calculate costs (paint1)
2927dd7cddfSDavid du Colombier 	 */
2937dd7cddfSDavid du Colombier 	r = firstr;
2947dd7cddfSDavid du Colombier 	if(r) {
2957dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
2967dd7cddfSDavid du Colombier 			bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
2977dd7cddfSDavid du Colombier 			  ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
2987dd7cddfSDavid du Colombier 		if(bany(&bit)) {
2997dd7cddfSDavid du Colombier 			nearln = r->prog->lineno;
3007dd7cddfSDavid du Colombier 			warn(Z, "used and not set: %B", bit);
3017dd7cddfSDavid du Colombier 			if(debug['R'] && !debug['w'])
3027dd7cddfSDavid du Colombier 				print("used and not set: %B\n", bit);
3037dd7cddfSDavid du Colombier 		}
3047dd7cddfSDavid du Colombier 	}
3057dd7cddfSDavid du Colombier 	if(debug['R'] && debug['v'])
3067dd7cddfSDavid du Colombier 		print("\nprop structure:\n");
3077dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link)
3087dd7cddfSDavid du Colombier 		r->act = zbits;
3097dd7cddfSDavid du Colombier 	rgp = region;
3107dd7cddfSDavid du Colombier 	nregion = 0;
3117dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
3127dd7cddfSDavid du Colombier 		if(debug['R'] && debug['v'])
3137dd7cddfSDavid du Colombier 			print("%P\n	set = %B; rah = %B; cal = %B\n",
3147dd7cddfSDavid du Colombier 				r->prog, r->set, r->refahead, r->calahead);
3157dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
3167dd7cddfSDavid du Colombier 			bit.b[z] = r->set.b[z] &
3177dd7cddfSDavid du Colombier 			  ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
3187dd7cddfSDavid du Colombier 		if(bany(&bit)) {
3197dd7cddfSDavid du Colombier 			nearln = r->prog->lineno;
3207dd7cddfSDavid du Colombier 			warn(Z, "set and not used: %B", bit);
3217dd7cddfSDavid du Colombier 			if(debug['R'])
3227dd7cddfSDavid du Colombier 				print("set an not used: %B\n", bit);
3237dd7cddfSDavid du Colombier 			excise(r);
3247dd7cddfSDavid du Colombier 		}
3257dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
3267dd7cddfSDavid du Colombier 			bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
3277dd7cddfSDavid du Colombier 		while(bany(&bit)) {
3287dd7cddfSDavid du Colombier 			i = bnum(bit);
3297dd7cddfSDavid du Colombier 			rgp->enter = r;
3307dd7cddfSDavid du Colombier 			rgp->varno = i;
3317dd7cddfSDavid du Colombier 			change = 0;
3327dd7cddfSDavid du Colombier 			if(debug['R'] && debug['v'])
3337dd7cddfSDavid du Colombier 				print("\n");
3347dd7cddfSDavid du Colombier 			paint1(r, i);
3357dd7cddfSDavid du Colombier 			bit.b[i/32] &= ~(1L<<(i%32));
3367dd7cddfSDavid du Colombier 			if(change <= 0) {
3377dd7cddfSDavid du Colombier 				if(debug['R'])
3387dd7cddfSDavid du Colombier 					print("%L$%d: %B\n",
3397dd7cddfSDavid du Colombier 						r->prog->lineno, change, blsh(i));
3407dd7cddfSDavid du Colombier 				continue;
3417dd7cddfSDavid du Colombier 			}
3427dd7cddfSDavid du Colombier 			rgp->cost = change;
3437dd7cddfSDavid du Colombier 			nregion++;
3447dd7cddfSDavid du Colombier 			if(nregion >= NRGN) {
3457dd7cddfSDavid du Colombier 				warn(Z, "too many regions");
3467dd7cddfSDavid du Colombier 				goto brk;
3477dd7cddfSDavid du Colombier 			}
3487dd7cddfSDavid du Colombier 			rgp++;
3497dd7cddfSDavid du Colombier 		}
3507dd7cddfSDavid du Colombier 	}
3517dd7cddfSDavid du Colombier brk:
3527dd7cddfSDavid du Colombier 	qsort(region, nregion, sizeof(region[0]), rcmp);
3537dd7cddfSDavid du Colombier 
3547dd7cddfSDavid du Colombier 	/*
3557dd7cddfSDavid du Colombier 	 * pass 6
3567dd7cddfSDavid du Colombier 	 * determine used registers (paint2)
3577dd7cddfSDavid du Colombier 	 * replace code (paint3)
3587dd7cddfSDavid du Colombier 	 */
3597dd7cddfSDavid du Colombier 	rgp = region;
3607dd7cddfSDavid du Colombier 	for(i=0; i<nregion; i++) {
3617dd7cddfSDavid du Colombier 		bit = blsh(rgp->varno);
3627dd7cddfSDavid du Colombier 		vreg = paint2(rgp->enter, rgp->varno);
3637dd7cddfSDavid du Colombier 		vreg = allreg(vreg, rgp);
3647dd7cddfSDavid du Colombier 		if(debug['R']) {
3657dd7cddfSDavid du Colombier 			if(rgp->regno >= NREG)
3667dd7cddfSDavid du Colombier 				print("%L$%d F%d: %B\n",
3677dd7cddfSDavid du Colombier 					rgp->enter->prog->lineno,
3687dd7cddfSDavid du Colombier 					rgp->cost,
3697dd7cddfSDavid du Colombier 					rgp->regno-NREG,
3707dd7cddfSDavid du Colombier 					bit);
3717dd7cddfSDavid du Colombier 			else
3727dd7cddfSDavid du Colombier 				print("%L$%d R%d: %B\n",
3737dd7cddfSDavid du Colombier 					rgp->enter->prog->lineno,
3747dd7cddfSDavid du Colombier 					rgp->cost,
3757dd7cddfSDavid du Colombier 					rgp->regno,
3767dd7cddfSDavid du Colombier 					bit);
3777dd7cddfSDavid du Colombier 		}
3787dd7cddfSDavid du Colombier 		if(rgp->regno != 0)
3797dd7cddfSDavid du Colombier 			paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
3807dd7cddfSDavid du Colombier 		rgp++;
3817dd7cddfSDavid du Colombier 	}
3827dd7cddfSDavid du Colombier 	/*
3837dd7cddfSDavid du Colombier 	 * pass 7
3847dd7cddfSDavid du Colombier 	 * peep-hole on basic block
3857dd7cddfSDavid du Colombier 	 */
3867dd7cddfSDavid du Colombier 	if(!debug['R'] || debug['P'])
3877dd7cddfSDavid du Colombier 		peep();
3887dd7cddfSDavid du Colombier 
3897dd7cddfSDavid du Colombier 	/*
3907dd7cddfSDavid du Colombier 	 * pass 8
3917dd7cddfSDavid du Colombier 	 * recalculate pc
3927dd7cddfSDavid du Colombier 	 */
3937dd7cddfSDavid du Colombier 	val = initpc;
3947dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r1) {
3957dd7cddfSDavid du Colombier 		r->pc = val;
3967dd7cddfSDavid du Colombier 		p = r->prog;
3977dd7cddfSDavid du Colombier 		p1 = P;
3987dd7cddfSDavid du Colombier 		r1 = r->link;
3997dd7cddfSDavid du Colombier 		if(r1 != R)
4007dd7cddfSDavid du Colombier 			p1 = r1->prog;
4017dd7cddfSDavid du Colombier 		for(; p != p1; p = p->link) {
4027dd7cddfSDavid du Colombier 			switch(p->as) {
4037dd7cddfSDavid du Colombier 			default:
4047dd7cddfSDavid du Colombier 				val++;
4057dd7cddfSDavid du Colombier 				break;
4067dd7cddfSDavid du Colombier 
4077dd7cddfSDavid du Colombier 			case ANOP:
4087dd7cddfSDavid du Colombier 			case ADATA:
4097dd7cddfSDavid du Colombier 			case AGLOBL:
4107dd7cddfSDavid du Colombier 			case ANAME:
411*375daca8SDavid du Colombier 			case ASIGNAME:
4127dd7cddfSDavid du Colombier 				break;
4137dd7cddfSDavid du Colombier 			}
4147dd7cddfSDavid du Colombier 		}
4157dd7cddfSDavid du Colombier 	}
4167dd7cddfSDavid du Colombier 	pc = val;
4177dd7cddfSDavid du Colombier 
4187dd7cddfSDavid du Colombier 	/*
4197dd7cddfSDavid du Colombier 	 * fix up branches
4207dd7cddfSDavid du Colombier 	 */
4217dd7cddfSDavid du Colombier 	if(debug['R'])
4227dd7cddfSDavid du Colombier 		if(bany(&addrs))
4237dd7cddfSDavid du Colombier 			print("addrs: %B\n", addrs);
4247dd7cddfSDavid du Colombier 
4257dd7cddfSDavid du Colombier 	r1 = 0; /* set */
4267dd7cddfSDavid du Colombier 	for(r = firstr; r != R; r = r->link) {
4277dd7cddfSDavid du Colombier 		p = r->prog;
4287dd7cddfSDavid du Colombier 		if(p->to.type == D_BRANCH)
4297dd7cddfSDavid du Colombier 			p->to.offset = r->s2->pc;
4307dd7cddfSDavid du Colombier 		r1 = r;
4317dd7cddfSDavid du Colombier 	}
4327dd7cddfSDavid du Colombier 
4337dd7cddfSDavid du Colombier 	/*
4347dd7cddfSDavid du Colombier 	 * last pass
4357dd7cddfSDavid du Colombier 	 * eliminate nops
4367dd7cddfSDavid du Colombier 	 * free aux structures
4377dd7cddfSDavid du Colombier 	 */
4387dd7cddfSDavid du Colombier 	for(p = firstr->prog; p != P; p = p->link){
4397dd7cddfSDavid du Colombier 		while(p->link && p->link->as == ANOP)
4407dd7cddfSDavid du Colombier 			p->link = p->link->link;
4417dd7cddfSDavid du Colombier 	}
4427dd7cddfSDavid du Colombier 	if(r1 != R) {
4437dd7cddfSDavid du Colombier 		r1->link = freer;
4447dd7cddfSDavid du Colombier 		freer = firstr;
4457dd7cddfSDavid du Colombier 	}
4467dd7cddfSDavid du Colombier }
4477dd7cddfSDavid du Colombier 
4487dd7cddfSDavid du Colombier /*
4497dd7cddfSDavid du Colombier  * add mov b,rn
4507dd7cddfSDavid du Colombier  * just after r
4517dd7cddfSDavid du Colombier  */
4527dd7cddfSDavid du Colombier void
addmove(Reg * r,int bn,int rn,int f)4537dd7cddfSDavid du Colombier addmove(Reg *r, int bn, int rn, int f)
4547dd7cddfSDavid du Colombier {
4557dd7cddfSDavid du Colombier 	Prog *p, *p1;
4567dd7cddfSDavid du Colombier 	Adr *a;
4577dd7cddfSDavid du Colombier 	Var *v;
4587dd7cddfSDavid du Colombier 
4597dd7cddfSDavid du Colombier 	p1 = alloc(sizeof(*p1));
4607dd7cddfSDavid du Colombier 	*p1 = zprog;
4617dd7cddfSDavid du Colombier 	p = r->prog;
4627dd7cddfSDavid du Colombier 
4637dd7cddfSDavid du Colombier 	p1->link = p->link;
4647dd7cddfSDavid du Colombier 	p->link = p1;
4657dd7cddfSDavid du Colombier 	p1->lineno = p->lineno;
4667dd7cddfSDavid du Colombier 
4677dd7cddfSDavid du Colombier 	v = var + bn;
4687dd7cddfSDavid du Colombier 
4697dd7cddfSDavid du Colombier 	a = &p1->to;
4707dd7cddfSDavid du Colombier 	a->sym = v->sym;
4717dd7cddfSDavid du Colombier 	a->name = v->name;
4727dd7cddfSDavid du Colombier 	a->offset = v->offset;
4737dd7cddfSDavid du Colombier 	a->etype = v->etype;
4747dd7cddfSDavid du Colombier 	a->type = D_OREG;
4757dd7cddfSDavid du Colombier 	if(a->etype == TARRAY || a->sym == S)
4767dd7cddfSDavid du Colombier 		a->type = D_CONST;
4777dd7cddfSDavid du Colombier 
4787dd7cddfSDavid du Colombier 	p1->as = AMOVW;
4797dd7cddfSDavid du Colombier 	if(v->etype == TCHAR || v->etype == TUCHAR)
4807dd7cddfSDavid du Colombier 		p1->as = AMOVB;
4817dd7cddfSDavid du Colombier 	if(v->etype == TSHORT || v->etype == TUSHORT)
4827dd7cddfSDavid du Colombier 		p1->as = AMOVH;
4837dd7cddfSDavid du Colombier 	if(v->etype == TFLOAT)
4847dd7cddfSDavid du Colombier 		p1->as = AFMOVS;
4857dd7cddfSDavid du Colombier 	if(v->etype == TDOUBLE)
4867dd7cddfSDavid du Colombier 		p1->as = AFMOVD;
4877dd7cddfSDavid du Colombier 
4887dd7cddfSDavid du Colombier 	p1->from.type = D_REG;
4897dd7cddfSDavid du Colombier 	p1->from.reg = rn;
4907dd7cddfSDavid du Colombier 	if(rn >= NREG) {
4917dd7cddfSDavid du Colombier 		p1->from.type = D_FREG;
4927dd7cddfSDavid du Colombier 		p1->from.reg = rn-NREG;
4937dd7cddfSDavid du Colombier 	}
4947dd7cddfSDavid du Colombier 	if(!f) {
4957dd7cddfSDavid du Colombier 		p1->from = *a;
4967dd7cddfSDavid du Colombier 		*a = zprog.from;
4977dd7cddfSDavid du Colombier 		a->type = D_REG;
4987dd7cddfSDavid du Colombier 		a->reg = rn;
4997dd7cddfSDavid du Colombier 		if(rn >= NREG) {
5007dd7cddfSDavid du Colombier 			a->type = D_FREG;
5017dd7cddfSDavid du Colombier 			a->reg = rn-NREG;
5027dd7cddfSDavid du Colombier 		}
5037dd7cddfSDavid du Colombier 		if(v->etype == TUCHAR)
5047dd7cddfSDavid du Colombier 			p1->as = AMOVBZ;
5057dd7cddfSDavid du Colombier 		if(v->etype == TUSHORT)
5067dd7cddfSDavid du Colombier 			p1->as = AMOVHZ;
5077dd7cddfSDavid du Colombier 	}
5087dd7cddfSDavid du Colombier 	if(debug['R'])
5099a747e4fSDavid du Colombier 		print("%P\t.a%P\n", p, p1);
5107dd7cddfSDavid du Colombier }
5117dd7cddfSDavid du Colombier 
5127dd7cddfSDavid du Colombier Bits
mkvar(Adr * a,int docon)5137dd7cddfSDavid du Colombier mkvar(Adr *a, int docon)
5147dd7cddfSDavid du Colombier {
5157dd7cddfSDavid du Colombier 	Var *v;
5167dd7cddfSDavid du Colombier 	int i, t, n, et, z;
5177dd7cddfSDavid du Colombier 	long o;
5187dd7cddfSDavid du Colombier 	Bits bit;
5197dd7cddfSDavid du Colombier 	Sym *s;
5207dd7cddfSDavid du Colombier 
5217dd7cddfSDavid du Colombier 	t = a->type;
5227dd7cddfSDavid du Colombier 	if(t == D_REG && a->reg != NREG)
5237dd7cddfSDavid du Colombier 		regbits |= RtoB(a->reg);
5247dd7cddfSDavid du Colombier 	if(t == D_FREG && a->reg != NREG)
5257dd7cddfSDavid du Colombier 		regbits |= FtoB(a->reg);
5267dd7cddfSDavid du Colombier 	s = a->sym;
5277dd7cddfSDavid du Colombier 	o = a->offset;
5287dd7cddfSDavid du Colombier 	et = a->etype;
5297dd7cddfSDavid du Colombier 	if(s == S) {
5307dd7cddfSDavid du Colombier 		if(t != D_CONST || !docon || a->reg != NREG)
5317dd7cddfSDavid du Colombier 			goto none;
5327dd7cddfSDavid du Colombier 		et = TLONG;
5337dd7cddfSDavid du Colombier 	}
5347dd7cddfSDavid du Colombier 	if(t == D_CONST) {
5357dd7cddfSDavid du Colombier 		if(s == S && sval(o))
5367dd7cddfSDavid du Colombier 			goto none;
5377dd7cddfSDavid du Colombier 	}
5387dd7cddfSDavid du Colombier 	n = a->name;
5397dd7cddfSDavid du Colombier 	v = var;
5407dd7cddfSDavid du Colombier 	for(i=0; i<nvar; i++) {
5417dd7cddfSDavid du Colombier 		if(s == v->sym)
5427dd7cddfSDavid du Colombier 		if(n == v->name)
5437dd7cddfSDavid du Colombier 		if(o == v->offset)
5447dd7cddfSDavid du Colombier 			goto out;
5457dd7cddfSDavid du Colombier 		v++;
5467dd7cddfSDavid du Colombier 	}
5477dd7cddfSDavid du Colombier 	if(s)
5487dd7cddfSDavid du Colombier 		if(s->name[0] == '.')
5497dd7cddfSDavid du Colombier 			goto none;
5507dd7cddfSDavid du Colombier 	if(nvar >= NVAR) {
5517dd7cddfSDavid du Colombier 		if(debug['w'] > 1 && s)
5527dd7cddfSDavid du Colombier 			warn(Z, "variable not optimized: %s", s->name);
5537dd7cddfSDavid du Colombier 		goto none;
5547dd7cddfSDavid du Colombier 	}
5557dd7cddfSDavid du Colombier 	i = nvar;
5567dd7cddfSDavid du Colombier 	nvar++;
5577dd7cddfSDavid du Colombier 	v = &var[i];
5587dd7cddfSDavid du Colombier 	v->sym = s;
5597dd7cddfSDavid du Colombier 	v->offset = o;
5607dd7cddfSDavid du Colombier 	v->etype = et;
5617dd7cddfSDavid du Colombier 	v->name = n;
5627dd7cddfSDavid du Colombier 	if(debug['R'])
5637dd7cddfSDavid du Colombier 		print("bit=%2d et=%2d %D\n", i, et, a);
5647dd7cddfSDavid du Colombier out:
5657dd7cddfSDavid du Colombier 	bit = blsh(i);
5667dd7cddfSDavid du Colombier 	if(n == D_EXTERN || n == D_STATIC)
5677dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
5687dd7cddfSDavid du Colombier 			externs.b[z] |= bit.b[z];
5697dd7cddfSDavid du Colombier 	if(n == D_PARAM)
5707dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
5717dd7cddfSDavid du Colombier 			params.b[z] |= bit.b[z];
5727dd7cddfSDavid du Colombier 	if(v->etype != et || !typechlpfd[et])	/* funny punning */
5737dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
5747dd7cddfSDavid du Colombier 			addrs.b[z] |= bit.b[z];
5757dd7cddfSDavid du Colombier 	if(t == D_CONST) {
5767dd7cddfSDavid du Colombier 		if(s == S) {
5777dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++)
5787dd7cddfSDavid du Colombier 				consts.b[z] |= bit.b[z];
5797dd7cddfSDavid du Colombier 			return bit;
5807dd7cddfSDavid du Colombier 		}
5817dd7cddfSDavid du Colombier 		if(et != TARRAY)
5827dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++)
5837dd7cddfSDavid du Colombier 				addrs.b[z] |= bit.b[z];
5847dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
5857dd7cddfSDavid du Colombier 			params.b[z] |= bit.b[z];
5867dd7cddfSDavid du Colombier 		return bit;
5877dd7cddfSDavid du Colombier 	}
5887dd7cddfSDavid du Colombier 	if(t == D_OREG)
5897dd7cddfSDavid du Colombier 		return bit;
5907dd7cddfSDavid du Colombier 
5917dd7cddfSDavid du Colombier none:
5927dd7cddfSDavid du Colombier 	return zbits;
5937dd7cddfSDavid du Colombier }
5947dd7cddfSDavid du Colombier 
5957dd7cddfSDavid du Colombier void
prop(Reg * r,Bits ref,Bits cal)5967dd7cddfSDavid du Colombier prop(Reg *r, Bits ref, Bits cal)
5977dd7cddfSDavid du Colombier {
5987dd7cddfSDavid du Colombier 	Reg *r1, *r2;
5997dd7cddfSDavid du Colombier 	int z;
6007dd7cddfSDavid du Colombier 
6017dd7cddfSDavid du Colombier 	for(r1 = r; r1 != R; r1 = r1->p1) {
6027dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++) {
6037dd7cddfSDavid du Colombier 			ref.b[z] |= r1->refahead.b[z];
6047dd7cddfSDavid du Colombier 			if(ref.b[z] != r1->refahead.b[z]) {
6057dd7cddfSDavid du Colombier 				r1->refahead.b[z] = ref.b[z];
6067dd7cddfSDavid du Colombier 				change++;
6077dd7cddfSDavid du Colombier 			}
6087dd7cddfSDavid du Colombier 			cal.b[z] |= r1->calahead.b[z];
6097dd7cddfSDavid du Colombier 			if(cal.b[z] != r1->calahead.b[z]) {
6107dd7cddfSDavid du Colombier 				r1->calahead.b[z] = cal.b[z];
6117dd7cddfSDavid du Colombier 				change++;
6127dd7cddfSDavid du Colombier 			}
6137dd7cddfSDavid du Colombier 		}
6147dd7cddfSDavid du Colombier 		switch(r1->prog->as) {
6157dd7cddfSDavid du Colombier 		case ABL:
6167dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++) {
6177dd7cddfSDavid du Colombier 				cal.b[z] |= ref.b[z] | externs.b[z];
6187dd7cddfSDavid du Colombier 				ref.b[z] = 0;
6197dd7cddfSDavid du Colombier 			}
6207dd7cddfSDavid du Colombier 			break;
6217dd7cddfSDavid du Colombier 
6227dd7cddfSDavid du Colombier 		case ATEXT:
6237dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++) {
6247dd7cddfSDavid du Colombier 				cal.b[z] = 0;
6257dd7cddfSDavid du Colombier 				ref.b[z] = 0;
6267dd7cddfSDavid du Colombier 			}
6277dd7cddfSDavid du Colombier 			break;
6287dd7cddfSDavid du Colombier 
6297dd7cddfSDavid du Colombier 		case ARETURN:
6307dd7cddfSDavid du Colombier 			for(z=0; z<BITS; z++) {
6317dd7cddfSDavid du Colombier 				cal.b[z] = externs.b[z];
6327dd7cddfSDavid du Colombier 				ref.b[z] = 0;
6337dd7cddfSDavid du Colombier 			}
6347dd7cddfSDavid du Colombier 		}
6357dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++) {
6367dd7cddfSDavid du Colombier 			ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
6377dd7cddfSDavid du Colombier 				r1->use1.b[z] | r1->use2.b[z];
6387dd7cddfSDavid du Colombier 			cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
6397dd7cddfSDavid du Colombier 			r1->refbehind.b[z] = ref.b[z];
6407dd7cddfSDavid du Colombier 			r1->calbehind.b[z] = cal.b[z];
6417dd7cddfSDavid du Colombier 		}
6427dd7cddfSDavid du Colombier 		if(r1->active)
6437dd7cddfSDavid du Colombier 			break;
6447dd7cddfSDavid du Colombier 		r1->active = 1;
6457dd7cddfSDavid du Colombier 	}
6467dd7cddfSDavid du Colombier 	for(; r != r1; r = r->p1)
6477dd7cddfSDavid du Colombier 		for(r2 = r->p2; r2 != R; r2 = r2->p2link)
6487dd7cddfSDavid du Colombier 			prop(r2, r->refbehind, r->calbehind);
6497dd7cddfSDavid du Colombier }
6507dd7cddfSDavid du Colombier 
6517dd7cddfSDavid du Colombier /*
6527dd7cddfSDavid du Colombier  * find looping structure
6537dd7cddfSDavid du Colombier  *
6547dd7cddfSDavid du Colombier  * 1) find reverse postordering
6557dd7cddfSDavid du Colombier  * 2) find approximate dominators,
6567dd7cddfSDavid du Colombier  *	the actual dominators if the flow graph is reducible
6577dd7cddfSDavid du Colombier  *	otherwise, dominators plus some other non-dominators.
6587dd7cddfSDavid du Colombier  *	See Matthew S. Hecht and Jeffrey D. Ullman,
6597dd7cddfSDavid du Colombier  *	"Analysis of a Simple Algorithm for Global Data Flow Problems",
6607dd7cddfSDavid du Colombier  *	Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
6617dd7cddfSDavid du Colombier  *	Oct. 1-3, 1973, pp.  207-217.
6627dd7cddfSDavid du Colombier  * 3) find all nodes with a predecessor dominated by the current node.
6637dd7cddfSDavid du Colombier  *	such a node is a loop head.
6647dd7cddfSDavid du Colombier  *	recursively, all preds with a greater rpo number are in the loop
6657dd7cddfSDavid du Colombier  */
6667dd7cddfSDavid du Colombier long
postorder(Reg * r,Reg ** rpo2r,long n)6677dd7cddfSDavid du Colombier postorder(Reg *r, Reg **rpo2r, long n)
6687dd7cddfSDavid du Colombier {
6697dd7cddfSDavid du Colombier 	Reg *r1;
6707dd7cddfSDavid du Colombier 
6717dd7cddfSDavid du Colombier 	r->rpo = 1;
6727dd7cddfSDavid du Colombier 	r1 = r->s1;
6737dd7cddfSDavid du Colombier 	if(r1 && !r1->rpo)
6747dd7cddfSDavid du Colombier 		n = postorder(r1, rpo2r, n);
6757dd7cddfSDavid du Colombier 	r1 = r->s2;
6767dd7cddfSDavid du Colombier 	if(r1 && !r1->rpo)
6777dd7cddfSDavid du Colombier 		n = postorder(r1, rpo2r, n);
6787dd7cddfSDavid du Colombier 	rpo2r[n] = r;
6797dd7cddfSDavid du Colombier 	n++;
6807dd7cddfSDavid du Colombier 	return n;
6817dd7cddfSDavid du Colombier }
6827dd7cddfSDavid du Colombier 
6837dd7cddfSDavid du Colombier long
rpolca(long * idom,long rpo1,long rpo2)6847dd7cddfSDavid du Colombier rpolca(long *idom, long rpo1, long rpo2)
6857dd7cddfSDavid du Colombier {
6867dd7cddfSDavid du Colombier 	long t;
6877dd7cddfSDavid du Colombier 
6887dd7cddfSDavid du Colombier 	if(rpo1 == -1)
6897dd7cddfSDavid du Colombier 		return rpo2;
6907dd7cddfSDavid du Colombier 	while(rpo1 != rpo2){
6917dd7cddfSDavid du Colombier 		if(rpo1 > rpo2){
6927dd7cddfSDavid du Colombier 			t = rpo2;
6937dd7cddfSDavid du Colombier 			rpo2 = rpo1;
6947dd7cddfSDavid du Colombier 			rpo1 = t;
6957dd7cddfSDavid du Colombier 		}
6967dd7cddfSDavid du Colombier 		while(rpo1 < rpo2){
6977dd7cddfSDavid du Colombier 			t = idom[rpo2];
6987dd7cddfSDavid du Colombier 			if(t >= rpo2)
699*375daca8SDavid du Colombier 				fatal(Z, "bad idom");
7007dd7cddfSDavid du Colombier 			rpo2 = t;
7017dd7cddfSDavid du Colombier 		}
7027dd7cddfSDavid du Colombier 	}
7037dd7cddfSDavid du Colombier 	return rpo1;
7047dd7cddfSDavid du Colombier }
7057dd7cddfSDavid du Colombier 
7067dd7cddfSDavid du Colombier int
doms(long * idom,long r,long s)7077dd7cddfSDavid du Colombier doms(long *idom, long r, long s)
7087dd7cddfSDavid du Colombier {
7097dd7cddfSDavid du Colombier 	while(s > r)
7107dd7cddfSDavid du Colombier 		s = idom[s];
7117dd7cddfSDavid du Colombier 	return s == r;
7127dd7cddfSDavid du Colombier }
7137dd7cddfSDavid du Colombier 
7147dd7cddfSDavid du Colombier int
loophead(long * idom,Reg * r)7157dd7cddfSDavid du Colombier loophead(long *idom, Reg *r)
7167dd7cddfSDavid du Colombier {
7177dd7cddfSDavid du Colombier 	long src;
7187dd7cddfSDavid du Colombier 
7197dd7cddfSDavid du Colombier 	src = r->rpo;
7207dd7cddfSDavid du Colombier 	if(r->p1 != R && doms(idom, src, r->p1->rpo))
7217dd7cddfSDavid du Colombier 		return 1;
7227dd7cddfSDavid du Colombier 	for(r = r->p2; r != R; r = r->p2link)
7237dd7cddfSDavid du Colombier 		if(doms(idom, src, r->rpo))
7247dd7cddfSDavid du Colombier 			return 1;
7257dd7cddfSDavid du Colombier 	return 0;
7267dd7cddfSDavid du Colombier }
7277dd7cddfSDavid du Colombier 
7287dd7cddfSDavid du Colombier void
loopmark(Reg ** rpo2r,long head,Reg * r)7297dd7cddfSDavid du Colombier loopmark(Reg **rpo2r, long head, Reg *r)
7307dd7cddfSDavid du Colombier {
7317dd7cddfSDavid du Colombier 	if(r->rpo < head || r->active == head)
7327dd7cddfSDavid du Colombier 		return;
7337dd7cddfSDavid du Colombier 	r->active = head;
7347dd7cddfSDavid du Colombier 	r->loop += LOOP;
7357dd7cddfSDavid du Colombier 	if(r->p1 != R)
7367dd7cddfSDavid du Colombier 		loopmark(rpo2r, head, r->p1);
7377dd7cddfSDavid du Colombier 	for(r = r->p2; r != R; r = r->p2link)
7387dd7cddfSDavid du Colombier 		loopmark(rpo2r, head, r);
7397dd7cddfSDavid du Colombier }
7407dd7cddfSDavid du Colombier 
7417dd7cddfSDavid du Colombier void
loopit(Reg * r,long nr)7427dd7cddfSDavid du Colombier loopit(Reg *r, long nr)
7437dd7cddfSDavid du Colombier {
74459cc4ca5SDavid du Colombier 	Reg *r1;
74559cc4ca5SDavid du Colombier 	long i, d, me;
7467dd7cddfSDavid du Colombier 
74759cc4ca5SDavid du Colombier 	if(nr > maxnr) {
74859cc4ca5SDavid du Colombier 		rpo2r = alloc(nr * sizeof(Reg*));
74959cc4ca5SDavid du Colombier 		idom = alloc(nr * sizeof(long));
75059cc4ca5SDavid du Colombier 		maxnr = nr;
75159cc4ca5SDavid du Colombier 	}
75259cc4ca5SDavid du Colombier 
7537dd7cddfSDavid du Colombier 	d = postorder(r, rpo2r, 0);
7547dd7cddfSDavid du Colombier 	if(d > nr)
755*375daca8SDavid du Colombier 		fatal(Z, "too many reg nodes");
7567dd7cddfSDavid du Colombier 	nr = d;
7577dd7cddfSDavid du Colombier 	for(i = 0; i < nr / 2; i++){
7587dd7cddfSDavid du Colombier 		r1 = rpo2r[i];
7597dd7cddfSDavid du Colombier 		rpo2r[i] = rpo2r[nr - 1 - i];
7607dd7cddfSDavid du Colombier 		rpo2r[nr - 1 - i] = r1;
7617dd7cddfSDavid du Colombier 	}
7627dd7cddfSDavid du Colombier 	for(i = 0; i < nr; i++)
7637dd7cddfSDavid du Colombier 		rpo2r[i]->rpo = i;
7647dd7cddfSDavid du Colombier 
7657dd7cddfSDavid du Colombier 	idom[0] = 0;
7667dd7cddfSDavid du Colombier 	for(i = 0; i < nr; i++){
7677dd7cddfSDavid du Colombier 		r1 = rpo2r[i];
7687dd7cddfSDavid du Colombier 		me = r1->rpo;
7697dd7cddfSDavid du Colombier 		d = -1;
7707dd7cddfSDavid du Colombier 		if(r1->p1 != R && r1->p1->rpo < me)
7717dd7cddfSDavid du Colombier 			d = r1->p1->rpo;
7727dd7cddfSDavid du Colombier 		for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
7737dd7cddfSDavid du Colombier 			if(r1->rpo < me)
7747dd7cddfSDavid du Colombier 				d = rpolca(idom, d, r1->rpo);
7757dd7cddfSDavid du Colombier 		idom[i] = d;
7767dd7cddfSDavid du Colombier 	}
7777dd7cddfSDavid du Colombier 
7787dd7cddfSDavid du Colombier 	for(i = 0; i < nr; i++){
7797dd7cddfSDavid du Colombier 		r1 = rpo2r[i];
7807dd7cddfSDavid du Colombier 		r1->loop++;
7817dd7cddfSDavid du Colombier 		if(r1->p2 != R && loophead(idom, r1))
7827dd7cddfSDavid du Colombier 			loopmark(rpo2r, i, r1);
7837dd7cddfSDavid du Colombier 	}
7847dd7cddfSDavid du Colombier }
7857dd7cddfSDavid du Colombier 
7867dd7cddfSDavid du Colombier void
synch(Reg * r,Bits dif)7877dd7cddfSDavid du Colombier synch(Reg *r, Bits dif)
7887dd7cddfSDavid du Colombier {
7897dd7cddfSDavid du Colombier 	Reg *r1;
7907dd7cddfSDavid du Colombier 	int z;
7917dd7cddfSDavid du Colombier 
7927dd7cddfSDavid du Colombier 	for(r1 = r; r1 != R; r1 = r1->s1) {
7937dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++) {
7947dd7cddfSDavid du Colombier 			dif.b[z] = (dif.b[z] &
7957dd7cddfSDavid du Colombier 				~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
7967dd7cddfSDavid du Colombier 					r1->set.b[z] | r1->regdiff.b[z];
7977dd7cddfSDavid du Colombier 			if(dif.b[z] != r1->regdiff.b[z]) {
7987dd7cddfSDavid du Colombier 				r1->regdiff.b[z] = dif.b[z];
7997dd7cddfSDavid du Colombier 				change++;
8007dd7cddfSDavid du Colombier 			}
8017dd7cddfSDavid du Colombier 		}
8027dd7cddfSDavid du Colombier 		if(r1->active)
8037dd7cddfSDavid du Colombier 			break;
8047dd7cddfSDavid du Colombier 		r1->active = 1;
8057dd7cddfSDavid du Colombier 		for(z=0; z<BITS; z++)
8067dd7cddfSDavid du Colombier 			dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
8077dd7cddfSDavid du Colombier 		if(r1->s2 != R)
8087dd7cddfSDavid du Colombier 			synch(r1->s2, dif);
8097dd7cddfSDavid du Colombier 	}
8107dd7cddfSDavid du Colombier }
8117dd7cddfSDavid du Colombier 
8127dd7cddfSDavid du Colombier ulong
allreg(ulong b,Rgn * r)8137dd7cddfSDavid du Colombier allreg(ulong b, Rgn *r)
8147dd7cddfSDavid du Colombier {
8157dd7cddfSDavid du Colombier 	Var *v;
8167dd7cddfSDavid du Colombier 	int i;
8177dd7cddfSDavid du Colombier 
8187dd7cddfSDavid du Colombier 	v = var + r->varno;
8197dd7cddfSDavid du Colombier 	r->regno = 0;
8207dd7cddfSDavid du Colombier 	switch(v->etype) {
8217dd7cddfSDavid du Colombier 
8227dd7cddfSDavid du Colombier 	default:
8237dd7cddfSDavid du Colombier 		diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
8247dd7cddfSDavid du Colombier 		break;
8257dd7cddfSDavid du Colombier 
8267dd7cddfSDavid du Colombier 	case TCHAR:
8277dd7cddfSDavid du Colombier 	case TUCHAR:
8287dd7cddfSDavid du Colombier 	case TSHORT:
8297dd7cddfSDavid du Colombier 	case TUSHORT:
8307dd7cddfSDavid du Colombier 	case TINT:
8317dd7cddfSDavid du Colombier 	case TUINT:
8327dd7cddfSDavid du Colombier 	case TLONG:
8337dd7cddfSDavid du Colombier 	case TULONG:
8347dd7cddfSDavid du Colombier 	case TIND:
8357dd7cddfSDavid du Colombier 	case TARRAY:
8367dd7cddfSDavid du Colombier 		i = BtoR(~b);
8377dd7cddfSDavid du Colombier 		if(i && r->cost > 0) {
8387dd7cddfSDavid du Colombier 			r->regno = i;
8397dd7cddfSDavid du Colombier 			return RtoB(i);
8407dd7cddfSDavid du Colombier 		}
8417dd7cddfSDavid du Colombier 		break;
8427dd7cddfSDavid du Colombier 
8437dd7cddfSDavid du Colombier 	case TDOUBLE:
8447dd7cddfSDavid du Colombier 	case TFLOAT:
8457dd7cddfSDavid du Colombier 		i = BtoF(~b);
8467dd7cddfSDavid du Colombier 		if(i && r->cost > 0) {
8477dd7cddfSDavid du Colombier 			r->regno = i+NREG;
8487dd7cddfSDavid du Colombier 			return FtoB(i);
8497dd7cddfSDavid du Colombier 		}
8507dd7cddfSDavid du Colombier 		break;
8517dd7cddfSDavid du Colombier 	}
8527dd7cddfSDavid du Colombier 	return 0;
8537dd7cddfSDavid du Colombier }
8547dd7cddfSDavid du Colombier 
8557dd7cddfSDavid du Colombier void
paint1(Reg * r,int bn)8567dd7cddfSDavid du Colombier paint1(Reg *r, int bn)
8577dd7cddfSDavid du Colombier {
8587dd7cddfSDavid du Colombier 	Reg *r1;
8597dd7cddfSDavid du Colombier 	Prog *p;
8607dd7cddfSDavid du Colombier 	int z;
8617dd7cddfSDavid du Colombier 	ulong bb;
8627dd7cddfSDavid du Colombier 
8637dd7cddfSDavid du Colombier 	z = bn/32;
8647dd7cddfSDavid du Colombier 	bb = 1L<<(bn%32);
8657dd7cddfSDavid du Colombier 	if(r->act.b[z] & bb)
8667dd7cddfSDavid du Colombier 		return;
8677dd7cddfSDavid du Colombier 	for(;;) {
8687dd7cddfSDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
8697dd7cddfSDavid du Colombier 			break;
8707dd7cddfSDavid du Colombier 		r1 = r->p1;
8717dd7cddfSDavid du Colombier 		if(r1 == R)
8727dd7cddfSDavid du Colombier 			break;
8737dd7cddfSDavid du Colombier 		if(!(r1->refahead.b[z] & bb))
8747dd7cddfSDavid du Colombier 			break;
8757dd7cddfSDavid du Colombier 		if(r1->act.b[z] & bb)
8767dd7cddfSDavid du Colombier 			break;
8777dd7cddfSDavid du Colombier 		r = r1;
8787dd7cddfSDavid du Colombier 	}
8797dd7cddfSDavid du Colombier 
8807dd7cddfSDavid du Colombier 	if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
8817dd7cddfSDavid du Colombier 		change -= CLOAD * r->loop;
8827dd7cddfSDavid du Colombier 		if(debug['R'] && debug['v'])
8839a747e4fSDavid du Colombier 			print("%ld%P\tld %B $%d\n", r->loop,
8849a747e4fSDavid du Colombier 				r->prog, blsh(bn), change);
8857dd7cddfSDavid du Colombier 	}
8867dd7cddfSDavid du Colombier 	for(;;) {
8877dd7cddfSDavid du Colombier 		r->act.b[z] |= bb;
8887dd7cddfSDavid du Colombier 		p = r->prog;
8897dd7cddfSDavid du Colombier 
8907dd7cddfSDavid du Colombier 		if(r->use1.b[z] & bb) {
8917dd7cddfSDavid du Colombier 			change += CREF * r->loop;
8927dd7cddfSDavid du Colombier 			if(p->to.type == D_FREG && p->as == AMOVW)
8937dd7cddfSDavid du Colombier 				change = -CINF;		/* cant go Rreg to Freg */
8947dd7cddfSDavid du Colombier 			if(debug['R'] && debug['v'])
8959a747e4fSDavid du Colombier 				print("%ld%P\tu1 %B $%d\n", r->loop,
8969a747e4fSDavid du Colombier 					p, blsh(bn), change);
8977dd7cddfSDavid du Colombier 		}
8987dd7cddfSDavid du Colombier 
8997dd7cddfSDavid du Colombier 		if((r->use2.b[z]|r->set.b[z]) & bb) {
9007dd7cddfSDavid du Colombier 			change += CREF * r->loop;
9017dd7cddfSDavid du Colombier 			if(p->from.type == D_FREG && p->as == AMOVW)
9027dd7cddfSDavid du Colombier 				change = -CINF;		/* cant go Rreg to Freg */
9037dd7cddfSDavid du Colombier 			if(debug['R'] && debug['v'])
9049a747e4fSDavid du Colombier 				print("%ld%P\tu2 %B $%d\n", r->loop,
9059a747e4fSDavid du Colombier 					p, blsh(bn), change);
9067dd7cddfSDavid du Colombier 		}
9077dd7cddfSDavid du Colombier 
9087dd7cddfSDavid du Colombier 		if(STORE(r) & r->regdiff.b[z] & bb) {
9097dd7cddfSDavid du Colombier 			change -= CLOAD * r->loop;
9107dd7cddfSDavid du Colombier 			if(debug['R'] && debug['v'])
9119a747e4fSDavid du Colombier 				print("%ld%P\tst %B $%d\n", r->loop,
9129a747e4fSDavid du Colombier 					p, blsh(bn), change);
9137dd7cddfSDavid du Colombier 		}
9147dd7cddfSDavid du Colombier 
9157dd7cddfSDavid du Colombier 		if(r->refbehind.b[z] & bb)
9167dd7cddfSDavid du Colombier 			for(r1 = r->p2; r1 != R; r1 = r1->p2link)
9177dd7cddfSDavid du Colombier 				if(r1->refahead.b[z] & bb)
9187dd7cddfSDavid du Colombier 					paint1(r1, bn);
9197dd7cddfSDavid du Colombier 
9207dd7cddfSDavid du Colombier 		if(!(r->refahead.b[z] & bb))
9217dd7cddfSDavid du Colombier 			break;
9227dd7cddfSDavid du Colombier 		r1 = r->s2;
9237dd7cddfSDavid du Colombier 		if(r1 != R)
9247dd7cddfSDavid du Colombier 			if(r1->refbehind.b[z] & bb)
9257dd7cddfSDavid du Colombier 				paint1(r1, bn);
9267dd7cddfSDavid du Colombier 		r = r->s1;
9277dd7cddfSDavid du Colombier 		if(r == R)
9287dd7cddfSDavid du Colombier 			break;
9297dd7cddfSDavid du Colombier 		if(r->act.b[z] & bb)
9307dd7cddfSDavid du Colombier 			break;
9317dd7cddfSDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
9327dd7cddfSDavid du Colombier 			break;
9337dd7cddfSDavid du Colombier 	}
9347dd7cddfSDavid du Colombier }
9357dd7cddfSDavid du Colombier 
9367dd7cddfSDavid du Colombier ulong
paint2(Reg * r,int bn)9377dd7cddfSDavid du Colombier paint2(Reg *r, int bn)
9387dd7cddfSDavid du Colombier {
9397dd7cddfSDavid du Colombier 	Reg *r1;
9407dd7cddfSDavid du Colombier 	int z;
9417dd7cddfSDavid du Colombier 	ulong bb, vreg;
9427dd7cddfSDavid du Colombier 
9437dd7cddfSDavid du Colombier 	z = bn/32;
9447dd7cddfSDavid du Colombier 	bb = 1L << (bn%32);
9457dd7cddfSDavid du Colombier 	vreg = regbits;
9467dd7cddfSDavid du Colombier 	if(!(r->act.b[z] & bb))
9477dd7cddfSDavid du Colombier 		return vreg;
9487dd7cddfSDavid du Colombier 	for(;;) {
9497dd7cddfSDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
9507dd7cddfSDavid du Colombier 			break;
9517dd7cddfSDavid du Colombier 		r1 = r->p1;
9527dd7cddfSDavid du Colombier 		if(r1 == R)
9537dd7cddfSDavid du Colombier 			break;
9547dd7cddfSDavid du Colombier 		if(!(r1->refahead.b[z] & bb))
9557dd7cddfSDavid du Colombier 			break;
9567dd7cddfSDavid du Colombier 		if(!(r1->act.b[z] & bb))
9577dd7cddfSDavid du Colombier 			break;
9587dd7cddfSDavid du Colombier 		r = r1;
9597dd7cddfSDavid du Colombier 	}
9607dd7cddfSDavid du Colombier 	for(;;) {
9617dd7cddfSDavid du Colombier 		r->act.b[z] &= ~bb;
9627dd7cddfSDavid du Colombier 
9637dd7cddfSDavid du Colombier 		vreg |= r->regu;
9647dd7cddfSDavid du Colombier 
9657dd7cddfSDavid du Colombier 		if(r->refbehind.b[z] & bb)
9667dd7cddfSDavid du Colombier 			for(r1 = r->p2; r1 != R; r1 = r1->p2link)
9677dd7cddfSDavid du Colombier 				if(r1->refahead.b[z] & bb)
9687dd7cddfSDavid du Colombier 					vreg |= paint2(r1, bn);
9697dd7cddfSDavid du Colombier 
9707dd7cddfSDavid du Colombier 		if(!(r->refahead.b[z] & bb))
9717dd7cddfSDavid du Colombier 			break;
9727dd7cddfSDavid du Colombier 		r1 = r->s2;
9737dd7cddfSDavid du Colombier 		if(r1 != R)
9747dd7cddfSDavid du Colombier 			if(r1->refbehind.b[z] & bb)
9757dd7cddfSDavid du Colombier 				vreg |= paint2(r1, bn);
9767dd7cddfSDavid du Colombier 		r = r->s1;
9777dd7cddfSDavid du Colombier 		if(r == R)
9787dd7cddfSDavid du Colombier 			break;
9797dd7cddfSDavid du Colombier 		if(!(r->act.b[z] & bb))
9807dd7cddfSDavid du Colombier 			break;
9817dd7cddfSDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
9827dd7cddfSDavid du Colombier 			break;
9837dd7cddfSDavid du Colombier 	}
9847dd7cddfSDavid du Colombier 	return vreg;
9857dd7cddfSDavid du Colombier }
9867dd7cddfSDavid du Colombier 
9877dd7cddfSDavid du Colombier void
paint3(Reg * r,int bn,long rb,int rn)9887dd7cddfSDavid du Colombier paint3(Reg *r, int bn, long rb, int rn)
9897dd7cddfSDavid du Colombier {
9907dd7cddfSDavid du Colombier 	Reg *r1;
9917dd7cddfSDavid du Colombier 	Prog *p;
9927dd7cddfSDavid du Colombier 	int z;
9937dd7cddfSDavid du Colombier 	ulong bb;
9947dd7cddfSDavid du Colombier 
9957dd7cddfSDavid du Colombier 	z = bn/32;
9967dd7cddfSDavid du Colombier 	bb = 1L << (bn%32);
9977dd7cddfSDavid du Colombier 	if(r->act.b[z] & bb)
9987dd7cddfSDavid du Colombier 		return;
9997dd7cddfSDavid du Colombier 	for(;;) {
10007dd7cddfSDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
10017dd7cddfSDavid du Colombier 			break;
10027dd7cddfSDavid du Colombier 		r1 = r->p1;
10037dd7cddfSDavid du Colombier 		if(r1 == R)
10047dd7cddfSDavid du Colombier 			break;
10057dd7cddfSDavid du Colombier 		if(!(r1->refahead.b[z] & bb))
10067dd7cddfSDavid du Colombier 			break;
10077dd7cddfSDavid du Colombier 		if(r1->act.b[z] & bb)
10087dd7cddfSDavid du Colombier 			break;
10097dd7cddfSDavid du Colombier 		r = r1;
10107dd7cddfSDavid du Colombier 	}
10117dd7cddfSDavid du Colombier 
10127dd7cddfSDavid du Colombier 	if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
10137dd7cddfSDavid du Colombier 		addmove(r, bn, rn, 0);
10147dd7cddfSDavid du Colombier 	for(;;) {
10157dd7cddfSDavid du Colombier 		r->act.b[z] |= bb;
10167dd7cddfSDavid du Colombier 		p = r->prog;
10177dd7cddfSDavid du Colombier 
10187dd7cddfSDavid du Colombier 		if(r->use1.b[z] & bb) {
10197dd7cddfSDavid du Colombier 			if(debug['R'])
10207dd7cddfSDavid du Colombier 				print("%P", p);
10217dd7cddfSDavid du Colombier 			addreg(&p->from, rn);
10227dd7cddfSDavid du Colombier 			if(debug['R'])
10239a747e4fSDavid du Colombier 				print("\t.c%P\n", p);
10247dd7cddfSDavid du Colombier 		}
10257dd7cddfSDavid du Colombier 		if((r->use2.b[z]|r->set.b[z]) & bb) {
10267dd7cddfSDavid du Colombier 			if(debug['R'])
10277dd7cddfSDavid du Colombier 				print("%P", p);
10287dd7cddfSDavid du Colombier 			addreg(&p->to, rn);
10297dd7cddfSDavid du Colombier 			if(debug['R'])
10309a747e4fSDavid du Colombier 				print("\t.c%P\n", p);
10317dd7cddfSDavid du Colombier 		}
10327dd7cddfSDavid du Colombier 
10337dd7cddfSDavid du Colombier 		if(STORE(r) & r->regdiff.b[z] & bb)
10347dd7cddfSDavid du Colombier 			addmove(r, bn, rn, 1);
10357dd7cddfSDavid du Colombier 		r->regu |= rb;
10367dd7cddfSDavid du Colombier 
10377dd7cddfSDavid du Colombier 		if(r->refbehind.b[z] & bb)
10387dd7cddfSDavid du Colombier 			for(r1 = r->p2; r1 != R; r1 = r1->p2link)
10397dd7cddfSDavid du Colombier 				if(r1->refahead.b[z] & bb)
10407dd7cddfSDavid du Colombier 					paint3(r1, bn, rb, rn);
10417dd7cddfSDavid du Colombier 
10427dd7cddfSDavid du Colombier 		if(!(r->refahead.b[z] & bb))
10437dd7cddfSDavid du Colombier 			break;
10447dd7cddfSDavid du Colombier 		r1 = r->s2;
10457dd7cddfSDavid du Colombier 		if(r1 != R)
10467dd7cddfSDavid du Colombier 			if(r1->refbehind.b[z] & bb)
10477dd7cddfSDavid du Colombier 				paint3(r1, bn, rb, rn);
10487dd7cddfSDavid du Colombier 		r = r->s1;
10497dd7cddfSDavid du Colombier 		if(r == R)
10507dd7cddfSDavid du Colombier 			break;
10517dd7cddfSDavid du Colombier 		if(r->act.b[z] & bb)
10527dd7cddfSDavid du Colombier 			break;
10537dd7cddfSDavid du Colombier 		if(!(r->refbehind.b[z] & bb))
10547dd7cddfSDavid du Colombier 			break;
10557dd7cddfSDavid du Colombier 	}
10567dd7cddfSDavid du Colombier }
10577dd7cddfSDavid du Colombier 
10587dd7cddfSDavid du Colombier void
addreg(Adr * a,int rn)10597dd7cddfSDavid du Colombier addreg(Adr *a, int rn)
10607dd7cddfSDavid du Colombier {
10617dd7cddfSDavid du Colombier 
10627dd7cddfSDavid du Colombier 	a->sym = 0;
10637dd7cddfSDavid du Colombier 	a->name = D_NONE;
10647dd7cddfSDavid du Colombier 	a->type = D_REG;
10657dd7cddfSDavid du Colombier 	a->reg = rn;
10667dd7cddfSDavid du Colombier 	if(rn >= NREG) {
10677dd7cddfSDavid du Colombier 		a->type = D_FREG;
10687dd7cddfSDavid du Colombier 		a->reg = rn-NREG;
10697dd7cddfSDavid du Colombier 	}
10707dd7cddfSDavid du Colombier }
10717dd7cddfSDavid du Colombier 
10727dd7cddfSDavid du Colombier /*
10737dd7cddfSDavid du Colombier  * track register variables including external registers:
10747dd7cddfSDavid du Colombier  *	bit	reg
10757dd7cddfSDavid du Colombier  *	0	R7
10767dd7cddfSDavid du Colombier  *	1	R8
10777dd7cddfSDavid du Colombier  *	...	...
10787dd7cddfSDavid du Colombier  *	21	R28
10797dd7cddfSDavid du Colombier  */
10807dd7cddfSDavid du Colombier long
RtoB(int r)10817dd7cddfSDavid du Colombier RtoB(int r)
10827dd7cddfSDavid du Colombier {
10837dd7cddfSDavid du Colombier 
10847dd7cddfSDavid du Colombier 	if(r >= REGMIN && r <= REGMAX)
10857dd7cddfSDavid du Colombier 		return 1L << (r-REGMIN);
10867dd7cddfSDavid du Colombier 	return 0;
10877dd7cddfSDavid du Colombier }
10887dd7cddfSDavid du Colombier 
10897dd7cddfSDavid du Colombier int
BtoR(long b)10907dd7cddfSDavid du Colombier BtoR(long b)
10917dd7cddfSDavid du Colombier {
10927dd7cddfSDavid du Colombier 	b &= 0x001fffffL;
10937dd7cddfSDavid du Colombier 	if(b == 0)
10947dd7cddfSDavid du Colombier 		return 0;
10957dd7cddfSDavid du Colombier 	return bitno(b) + REGMIN;
10967dd7cddfSDavid du Colombier }
10977dd7cddfSDavid du Colombier 
10987dd7cddfSDavid du Colombier /*
10997dd7cddfSDavid du Colombier  *	bit	reg
11007dd7cddfSDavid du Colombier  *	22	F17
11017dd7cddfSDavid du Colombier  *	23	F18
11027dd7cddfSDavid du Colombier  *	...	...
11037dd7cddfSDavid du Colombier  *	31	F26
11047dd7cddfSDavid du Colombier  */
11057dd7cddfSDavid du Colombier long
FtoB(int f)11067dd7cddfSDavid du Colombier FtoB(int f)
11077dd7cddfSDavid du Colombier {
11087dd7cddfSDavid du Colombier 	if(f < FREGMIN || f > FREGEXT)
11097dd7cddfSDavid du Colombier 		return 0;
11107dd7cddfSDavid du Colombier 	return 1L << (f - FREGMIN + 22);
11117dd7cddfSDavid du Colombier }
11127dd7cddfSDavid du Colombier 
11137dd7cddfSDavid du Colombier int
BtoF(long b)11147dd7cddfSDavid du Colombier BtoF(long b)
11157dd7cddfSDavid du Colombier {
11167dd7cddfSDavid du Colombier 
11177dd7cddfSDavid du Colombier 	b &= 0xffc00000L;
11187dd7cddfSDavid du Colombier 	if(b == 0)
11197dd7cddfSDavid du Colombier 		return 0;
11207dd7cddfSDavid du Colombier 	return bitno(b) - 22 + FREGMIN;
11217dd7cddfSDavid du Colombier }
1122