xref: /inferno-os/utils/0l/sched.c (revision ce8e0d607a2bec33fcaac7237d0b5535e5b152a1)
174a4d8c2SCharles.Forsyth #include	"l.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth enum
474a4d8c2SCharles.Forsyth {
574a4d8c2SCharles.Forsyth 	E_HILO	= 1<<0,
674a4d8c2SCharles.Forsyth 	E_FCR	= 1<<1,
774a4d8c2SCharles.Forsyth 	E_MCR	= 1<<2,
874a4d8c2SCharles.Forsyth 	E_MEM	= 1<<3,
974a4d8c2SCharles.Forsyth 	E_MEMSP	= 1<<4,	/* uses offset and size */
1074a4d8c2SCharles.Forsyth 	E_MEMSB	= 1<<5,	/* uses offset and size */
1174a4d8c2SCharles.Forsyth 	ANYMEM	= E_MEM|E_MEMSP|E_MEMSB,
1274a4d8c2SCharles.Forsyth 	DELAY	= BRANCH|LOAD|FCMP,
1374a4d8c2SCharles.Forsyth };
1474a4d8c2SCharles.Forsyth 
1574a4d8c2SCharles.Forsyth typedef	struct	Sch	Sch;
1674a4d8c2SCharles.Forsyth typedef	struct	Dep	Dep;
1774a4d8c2SCharles.Forsyth 
1874a4d8c2SCharles.Forsyth struct	Dep
1974a4d8c2SCharles.Forsyth {
2074a4d8c2SCharles.Forsyth 	ulong	ireg;
2174a4d8c2SCharles.Forsyth 	ulong	freg;
2274a4d8c2SCharles.Forsyth 	ulong	cc;
2374a4d8c2SCharles.Forsyth };
2474a4d8c2SCharles.Forsyth struct	Sch
2574a4d8c2SCharles.Forsyth {
2674a4d8c2SCharles.Forsyth 	Prog	p;
2774a4d8c2SCharles.Forsyth 	Dep	set;
2874a4d8c2SCharles.Forsyth 	Dep	used;
2974a4d8c2SCharles.Forsyth 	long	soffset;
3074a4d8c2SCharles.Forsyth 	char	size;
3174a4d8c2SCharles.Forsyth 	char	nop;
3274a4d8c2SCharles.Forsyth 	char	comp;
3374a4d8c2SCharles.Forsyth };
3474a4d8c2SCharles.Forsyth 
3574a4d8c2SCharles.Forsyth void	markregused(Sch*, Prog*);
3674a4d8c2SCharles.Forsyth int	depend(Sch*, Sch*);
3774a4d8c2SCharles.Forsyth int	conflict(Sch*, Sch*);
3874a4d8c2SCharles.Forsyth int	offoverlap(Sch*, Sch*);
3974a4d8c2SCharles.Forsyth void	dumpbits(Sch*, Dep*);
4074a4d8c2SCharles.Forsyth 
4174a4d8c2SCharles.Forsyth void
sched(Prog * p0,Prog * pe)4274a4d8c2SCharles.Forsyth sched(Prog *p0, Prog *pe)
4374a4d8c2SCharles.Forsyth {
4474a4d8c2SCharles.Forsyth 	Prog *p, *q;
4574a4d8c2SCharles.Forsyth 	Sch sch[NSCHED], *s, *t, *u, *se, stmp;
4674a4d8c2SCharles.Forsyth 
4774a4d8c2SCharles.Forsyth 	/*
4874a4d8c2SCharles.Forsyth 	 * build side structure
4974a4d8c2SCharles.Forsyth 	 */
5074a4d8c2SCharles.Forsyth 	s = sch;
5174a4d8c2SCharles.Forsyth 	for(p=p0;; p=p->link) {
5274a4d8c2SCharles.Forsyth 		memset(s, 0, sizeof(*s));
5374a4d8c2SCharles.Forsyth 		s->p = *p;
5474a4d8c2SCharles.Forsyth 		markregused(s, p);
5574a4d8c2SCharles.Forsyth 		if(debug['X']) {
56*ce8e0d60Sforsyth 			Bprint(&bso, "%P\t\tset", &s->p);
5774a4d8c2SCharles.Forsyth 			dumpbits(s, &s->set);
5874a4d8c2SCharles.Forsyth 			Bprint(&bso, "; used");
5974a4d8c2SCharles.Forsyth 			dumpbits(s, &s->used);
6074a4d8c2SCharles.Forsyth 			if(s->comp)
6174a4d8c2SCharles.Forsyth 				Bprint(&bso, "; compound");
6274a4d8c2SCharles.Forsyth 			if(s->p.mark & LOAD)
6374a4d8c2SCharles.Forsyth 				Bprint(&bso, "; load");
6474a4d8c2SCharles.Forsyth 			if(s->p.mark & BRANCH)
6574a4d8c2SCharles.Forsyth 				Bprint(&bso, "; branch");
6674a4d8c2SCharles.Forsyth 			if(s->p.mark & FCMP)
6774a4d8c2SCharles.Forsyth 				Bprint(&bso, "; fcmp");
6874a4d8c2SCharles.Forsyth 			Bprint(&bso, "\n");
6974a4d8c2SCharles.Forsyth 		}
7074a4d8c2SCharles.Forsyth 		if(p == pe)
7174a4d8c2SCharles.Forsyth 			break;
7274a4d8c2SCharles.Forsyth 		s++;
7374a4d8c2SCharles.Forsyth 	}
7474a4d8c2SCharles.Forsyth 	se = s;
7574a4d8c2SCharles.Forsyth 
7674a4d8c2SCharles.Forsyth 	/*
7774a4d8c2SCharles.Forsyth 	 * prepass to move things around
7874a4d8c2SCharles.Forsyth 	 * does nothing, but tries to make
7974a4d8c2SCharles.Forsyth 	 * the actual scheduler work better
8074a4d8c2SCharles.Forsyth 	 */
8174a4d8c2SCharles.Forsyth 	for(s=sch; s<=se; s++) {
8274a4d8c2SCharles.Forsyth 		if(!(s->p.mark & LOAD))
8374a4d8c2SCharles.Forsyth 			continue;
8474a4d8c2SCharles.Forsyth 		/* always good to put nonconflict loads together */
8574a4d8c2SCharles.Forsyth 		for(t=s+1; t<=se; t++) {
8674a4d8c2SCharles.Forsyth 			if(!(t->p.mark & LOAD))
8774a4d8c2SCharles.Forsyth 				continue;
8874a4d8c2SCharles.Forsyth 			if(t->p.mark & BRANCH)
8974a4d8c2SCharles.Forsyth 				break;
9074a4d8c2SCharles.Forsyth 			if(conflict(s, t))
9174a4d8c2SCharles.Forsyth 				break;
9274a4d8c2SCharles.Forsyth 			for(u=t-1; u>s; u--)
9374a4d8c2SCharles.Forsyth 				if(depend(u, t))
9474a4d8c2SCharles.Forsyth 					goto no11;
9574a4d8c2SCharles.Forsyth 			u = s+1;
9674a4d8c2SCharles.Forsyth 			stmp = *t;
9774a4d8c2SCharles.Forsyth 			memmove(s+2, u, (uchar*)t - (uchar*)u);
9874a4d8c2SCharles.Forsyth 			*u = stmp;
9974a4d8c2SCharles.Forsyth 			break;
10074a4d8c2SCharles.Forsyth 		}
10174a4d8c2SCharles.Forsyth 	no11:
10274a4d8c2SCharles.Forsyth 
10374a4d8c2SCharles.Forsyth 		/* put schedule fodder above load */
10474a4d8c2SCharles.Forsyth 		for(t=s+1; t<=se; t++) {
10574a4d8c2SCharles.Forsyth 			if(t->p.mark & BRANCH)
10674a4d8c2SCharles.Forsyth 				break;
10774a4d8c2SCharles.Forsyth 			if(s > sch && conflict(s-1, t))
10874a4d8c2SCharles.Forsyth 				continue;
10974a4d8c2SCharles.Forsyth 			for(u=t-1; u>=s; u--)
11074a4d8c2SCharles.Forsyth 				if(depend(t, u))
11174a4d8c2SCharles.Forsyth 					goto no1;
11274a4d8c2SCharles.Forsyth 			stmp = *t;
11374a4d8c2SCharles.Forsyth 			memmove(s+1, s, (uchar*)t - (uchar*)s);
11474a4d8c2SCharles.Forsyth 			*s = stmp;
11574a4d8c2SCharles.Forsyth 			if(!(s->p.mark & LOAD))
11674a4d8c2SCharles.Forsyth 				break;
11774a4d8c2SCharles.Forsyth 		no1:;
11874a4d8c2SCharles.Forsyth 		}
11974a4d8c2SCharles.Forsyth 	}
12074a4d8c2SCharles.Forsyth 
12174a4d8c2SCharles.Forsyth 	for(s=se; s>=sch; s--) {
12274a4d8c2SCharles.Forsyth 		if(!(s->p.mark & DELAY))
12374a4d8c2SCharles.Forsyth 			continue;
12474a4d8c2SCharles.Forsyth 		if(s < se)
12574a4d8c2SCharles.Forsyth 			if(!conflict(s, s+1))
12674a4d8c2SCharles.Forsyth 				goto out3;
12774a4d8c2SCharles.Forsyth 		/*
12874a4d8c2SCharles.Forsyth 		 * s is load, s+1 is immediate use of result or end of block
12974a4d8c2SCharles.Forsyth 		 * t is the trial instruction to insert between s and s+1
13074a4d8c2SCharles.Forsyth 		 */
13174a4d8c2SCharles.Forsyth 		if(!debug['Y'])
13274a4d8c2SCharles.Forsyth 		for(t=s-1; t>=sch; t--) {
13374a4d8c2SCharles.Forsyth 			if(t->comp)
13474a4d8c2SCharles.Forsyth 				if(s->p.mark & BRANCH)
13574a4d8c2SCharles.Forsyth 					goto no2;
13674a4d8c2SCharles.Forsyth 			if(t->p.mark & DELAY)
13774a4d8c2SCharles.Forsyth 				if(s >= se || conflict(t, s+1))
13874a4d8c2SCharles.Forsyth 					goto no2;
13974a4d8c2SCharles.Forsyth 			for(u=t+1; u<=s; u++)
14074a4d8c2SCharles.Forsyth 				if(depend(u, t))
14174a4d8c2SCharles.Forsyth 					goto no2;
14274a4d8c2SCharles.Forsyth 			goto out2;
14374a4d8c2SCharles.Forsyth 		no2:;
14474a4d8c2SCharles.Forsyth 		}
14574a4d8c2SCharles.Forsyth 		if(debug['X'])
14674a4d8c2SCharles.Forsyth 			Bprint(&bso, "?l%P\n", &s->p);
14774a4d8c2SCharles.Forsyth 		if(s->p.mark & BRANCH)
14874a4d8c2SCharles.Forsyth 			s->nop = 1;
14974a4d8c2SCharles.Forsyth 		if(debug['v']) {
15074a4d8c2SCharles.Forsyth 			if(s->p.mark & LOAD) {
15174a4d8c2SCharles.Forsyth 				nop.load.count++;
15274a4d8c2SCharles.Forsyth 				nop.load.outof++;
15374a4d8c2SCharles.Forsyth 			}
15474a4d8c2SCharles.Forsyth 			if(s->p.mark & BRANCH) {
15574a4d8c2SCharles.Forsyth 				nop.branch.count++;
15674a4d8c2SCharles.Forsyth 				nop.branch.outof++;
15774a4d8c2SCharles.Forsyth 			}
15874a4d8c2SCharles.Forsyth 			if(s->p.mark & FCMP) {
15974a4d8c2SCharles.Forsyth 				nop.fcmp.count++;
16074a4d8c2SCharles.Forsyth 				nop.fcmp.outof++;
16174a4d8c2SCharles.Forsyth 			}
16274a4d8c2SCharles.Forsyth 		}
16374a4d8c2SCharles.Forsyth 		continue;
16474a4d8c2SCharles.Forsyth 
16574a4d8c2SCharles.Forsyth 	out2:
16674a4d8c2SCharles.Forsyth 		if(debug['X']) {
16774a4d8c2SCharles.Forsyth 			Bprint(&bso, "!l%P\n", &t->p);
16874a4d8c2SCharles.Forsyth 			Bprint(&bso, "%P\n", &s->p);
16974a4d8c2SCharles.Forsyth 		}
17074a4d8c2SCharles.Forsyth 		stmp = *t;
17174a4d8c2SCharles.Forsyth 		memmove(t, t+1, (uchar*)s - (uchar*)t);
17274a4d8c2SCharles.Forsyth 		*s = stmp;
17374a4d8c2SCharles.Forsyth 		s--;
17474a4d8c2SCharles.Forsyth 
17574a4d8c2SCharles.Forsyth 	out3:
17674a4d8c2SCharles.Forsyth 		if(debug['v']) {
17774a4d8c2SCharles.Forsyth 			if(s->p.mark & LOAD)
17874a4d8c2SCharles.Forsyth 				nop.load.outof++;
17974a4d8c2SCharles.Forsyth 			if(s->p.mark & BRANCH)
18074a4d8c2SCharles.Forsyth 				nop.branch.outof++;
18174a4d8c2SCharles.Forsyth 			if(s->p.mark & FCMP)
18274a4d8c2SCharles.Forsyth 				nop.fcmp.outof++;
18374a4d8c2SCharles.Forsyth 		}
18474a4d8c2SCharles.Forsyth 	}
18574a4d8c2SCharles.Forsyth 
18674a4d8c2SCharles.Forsyth 	/* Avoid HI/LO use->set */
18774a4d8c2SCharles.Forsyth 	t = sch+1;
18874a4d8c2SCharles.Forsyth 	for(s=sch; s<se-1; s++, t++) {
18974a4d8c2SCharles.Forsyth 		if((s->used.cc & E_HILO) == 0)
19074a4d8c2SCharles.Forsyth 			continue;
19174a4d8c2SCharles.Forsyth 		if(t->set.cc & E_HILO)
19274a4d8c2SCharles.Forsyth 			s->nop = 2;
19374a4d8c2SCharles.Forsyth 	}
19474a4d8c2SCharles.Forsyth 
19574a4d8c2SCharles.Forsyth 	/*
19674a4d8c2SCharles.Forsyth 	 * put it all back
19774a4d8c2SCharles.Forsyth 	 */
19874a4d8c2SCharles.Forsyth 	for(s=sch, p=p0; s<=se; s++, p=q) {
19974a4d8c2SCharles.Forsyth 		q = p->link;
20074a4d8c2SCharles.Forsyth 		if(q != s->p.link) {
20174a4d8c2SCharles.Forsyth 			*p = s->p;
20274a4d8c2SCharles.Forsyth 			p->link = q;
20374a4d8c2SCharles.Forsyth 		}
20474a4d8c2SCharles.Forsyth 		while(s->nop--)
20574a4d8c2SCharles.Forsyth 			addnop(p);
20674a4d8c2SCharles.Forsyth 	}
20774a4d8c2SCharles.Forsyth 	if(debug['X']) {
20874a4d8c2SCharles.Forsyth 		Bprint(&bso, "\n");
20974a4d8c2SCharles.Forsyth 		Bflush(&bso);
21074a4d8c2SCharles.Forsyth 	}
21174a4d8c2SCharles.Forsyth }
21274a4d8c2SCharles.Forsyth 
21374a4d8c2SCharles.Forsyth void
markregused(Sch * s,Prog * realp)21474a4d8c2SCharles.Forsyth markregused(Sch *s, Prog *realp)
21574a4d8c2SCharles.Forsyth {
21674a4d8c2SCharles.Forsyth 	int c, ar, ad, ld, sz;
21774a4d8c2SCharles.Forsyth 	ulong m;
21874a4d8c2SCharles.Forsyth 	Prog *p;
21974a4d8c2SCharles.Forsyth 
22074a4d8c2SCharles.Forsyth 	p = &s->p;
22174a4d8c2SCharles.Forsyth 	s->comp = compound(p);
22274a4d8c2SCharles.Forsyth 	s->nop = 0;
22374a4d8c2SCharles.Forsyth 	if(s->comp) {
22474a4d8c2SCharles.Forsyth 		s->set.ireg |= 1<<REGTMP;
22574a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGTMP;
22674a4d8c2SCharles.Forsyth 	}
22774a4d8c2SCharles.Forsyth 
22874a4d8c2SCharles.Forsyth 	ar = 0;		/* dest is really reference */
22974a4d8c2SCharles.Forsyth 	ad = 0;		/* source/dest is really address */
23074a4d8c2SCharles.Forsyth 	ld = 0;		/* opcode is load instruction */
23174a4d8c2SCharles.Forsyth 	sz = 20;	/* size of load/store for overlap computation */
23274a4d8c2SCharles.Forsyth 
23374a4d8c2SCharles.Forsyth /*
23474a4d8c2SCharles.Forsyth  * flags based on opcode
23574a4d8c2SCharles.Forsyth  */
23674a4d8c2SCharles.Forsyth 	switch(p->as) {
23774a4d8c2SCharles.Forsyth 	case ATEXT:
23874a4d8c2SCharles.Forsyth 		curtext = realp;
23974a4d8c2SCharles.Forsyth 		autosize = p->to.offset + 8;
24074a4d8c2SCharles.Forsyth 		ad = 1;
24174a4d8c2SCharles.Forsyth 		break;
24274a4d8c2SCharles.Forsyth 	case AJAL:
24374a4d8c2SCharles.Forsyth 		c = p->reg;
24474a4d8c2SCharles.Forsyth 		if(c == NREG)
24574a4d8c2SCharles.Forsyth 			c = REGLINK;
24674a4d8c2SCharles.Forsyth 		s->set.ireg |= 1<<c;
24774a4d8c2SCharles.Forsyth 		ar = 1;
24874a4d8c2SCharles.Forsyth 		ad = 1;
24974a4d8c2SCharles.Forsyth 		break;
25074a4d8c2SCharles.Forsyth 	case ABGEZAL:
25174a4d8c2SCharles.Forsyth 	case ABLTZAL:
25274a4d8c2SCharles.Forsyth 		s->set.ireg |= 1<<REGLINK;
25374a4d8c2SCharles.Forsyth 	case ABEQ:
25474a4d8c2SCharles.Forsyth 	case ABGEZ:
25574a4d8c2SCharles.Forsyth 	case ABGTZ:
25674a4d8c2SCharles.Forsyth 	case ABLEZ:
25774a4d8c2SCharles.Forsyth 	case ABLTZ:
25874a4d8c2SCharles.Forsyth 	case ABNE:
25974a4d8c2SCharles.Forsyth 		ar = 1;
26074a4d8c2SCharles.Forsyth 		ad = 1;
26174a4d8c2SCharles.Forsyth 		break;
26274a4d8c2SCharles.Forsyth 	case ABFPT:
26374a4d8c2SCharles.Forsyth 	case ABFPF:
26474a4d8c2SCharles.Forsyth 		ad = 1;
26574a4d8c2SCharles.Forsyth 		s->used.cc |= E_FCR;
26674a4d8c2SCharles.Forsyth 		break;
26774a4d8c2SCharles.Forsyth 	case ACMPEQD:
26874a4d8c2SCharles.Forsyth 	case ACMPEQF:
26974a4d8c2SCharles.Forsyth 	case ACMPGED:
27074a4d8c2SCharles.Forsyth 	case ACMPGEF:
27174a4d8c2SCharles.Forsyth 	case ACMPGTD:
27274a4d8c2SCharles.Forsyth 	case ACMPGTF:
27374a4d8c2SCharles.Forsyth 		ar = 1;
27474a4d8c2SCharles.Forsyth 		s->set.cc |= E_FCR;
27574a4d8c2SCharles.Forsyth 		p->mark |= FCMP;
27674a4d8c2SCharles.Forsyth 		break;
27774a4d8c2SCharles.Forsyth 	case AJMP:
27874a4d8c2SCharles.Forsyth 		ar = 1;
27974a4d8c2SCharles.Forsyth 		ad = 1;
28074a4d8c2SCharles.Forsyth 		break;
28174a4d8c2SCharles.Forsyth 	case AMOVB:
28274a4d8c2SCharles.Forsyth 	case AMOVBU:
28374a4d8c2SCharles.Forsyth 		sz = 1;
28474a4d8c2SCharles.Forsyth 		ld = 1;
28574a4d8c2SCharles.Forsyth 		break;
28674a4d8c2SCharles.Forsyth 	case AMOVH:
28774a4d8c2SCharles.Forsyth 	case AMOVHU:
28874a4d8c2SCharles.Forsyth 		sz = 2;
28974a4d8c2SCharles.Forsyth 		ld = 1;
29074a4d8c2SCharles.Forsyth 		break;
29174a4d8c2SCharles.Forsyth 	case AMOVF:
29274a4d8c2SCharles.Forsyth 	case AMOVW:
29374a4d8c2SCharles.Forsyth 	case AMOVWL:
29474a4d8c2SCharles.Forsyth 	case AMOVWR:
29574a4d8c2SCharles.Forsyth 		sz = 4;
29674a4d8c2SCharles.Forsyth 		ld = 1;
29774a4d8c2SCharles.Forsyth 		break;
29874a4d8c2SCharles.Forsyth 	case AMOVD:
29974a4d8c2SCharles.Forsyth 	case AMOVV:
30074a4d8c2SCharles.Forsyth 	case AMOVVL:
30174a4d8c2SCharles.Forsyth 	case AMOVVR:
30274a4d8c2SCharles.Forsyth 		sz = 8;
30374a4d8c2SCharles.Forsyth 		ld = 1;
30474a4d8c2SCharles.Forsyth 		break;
30574a4d8c2SCharles.Forsyth 	case ADIV:
30674a4d8c2SCharles.Forsyth 	case ADIVU:
30774a4d8c2SCharles.Forsyth 	case AMUL:
30874a4d8c2SCharles.Forsyth 	case AMULU:
30974a4d8c2SCharles.Forsyth 	case AREM:
31074a4d8c2SCharles.Forsyth 	case AREMU:
31174a4d8c2SCharles.Forsyth 	case ADIVV:
31274a4d8c2SCharles.Forsyth 	case ADIVVU:
31374a4d8c2SCharles.Forsyth 	case AMULV:
31474a4d8c2SCharles.Forsyth 	case AMULVU:
31574a4d8c2SCharles.Forsyth 	case AREMV:
31674a4d8c2SCharles.Forsyth 	case AREMVU:
31774a4d8c2SCharles.Forsyth 		s->set.cc = E_HILO;
31874a4d8c2SCharles.Forsyth 	case AADD:
31974a4d8c2SCharles.Forsyth 	case AADDU:
32074a4d8c2SCharles.Forsyth 	case AADDV:
32174a4d8c2SCharles.Forsyth 	case AADDVU:
32274a4d8c2SCharles.Forsyth 	case AAND:
32374a4d8c2SCharles.Forsyth 	case ANOR:
32474a4d8c2SCharles.Forsyth 	case AOR:
32574a4d8c2SCharles.Forsyth 	case ASGT:
32674a4d8c2SCharles.Forsyth 	case ASGTU:
32774a4d8c2SCharles.Forsyth 	case ASLL:
32874a4d8c2SCharles.Forsyth 	case ASRA:
32974a4d8c2SCharles.Forsyth 	case ASRL:
33074a4d8c2SCharles.Forsyth 	case ASLLV:
33174a4d8c2SCharles.Forsyth 	case ASRAV:
33274a4d8c2SCharles.Forsyth 	case ASRLV:
33374a4d8c2SCharles.Forsyth 	case ASUB:
33474a4d8c2SCharles.Forsyth 	case ASUBU:
33574a4d8c2SCharles.Forsyth 	case ASUBV:
33674a4d8c2SCharles.Forsyth 	case ASUBVU:
33774a4d8c2SCharles.Forsyth 	case AXOR:
33874a4d8c2SCharles.Forsyth 
33974a4d8c2SCharles.Forsyth 	case AADDD:
34074a4d8c2SCharles.Forsyth 	case AADDF:
34174a4d8c2SCharles.Forsyth 	case AADDW:
34274a4d8c2SCharles.Forsyth 	case ASUBD:
34374a4d8c2SCharles.Forsyth 	case ASUBF:
34474a4d8c2SCharles.Forsyth 	case ASUBW:
34574a4d8c2SCharles.Forsyth 	case AMULF:
34674a4d8c2SCharles.Forsyth 	case AMULD:
34774a4d8c2SCharles.Forsyth 	case AMULW:
34874a4d8c2SCharles.Forsyth 	case ADIVF:
34974a4d8c2SCharles.Forsyth 	case ADIVD:
35074a4d8c2SCharles.Forsyth 	case ADIVW:
35174a4d8c2SCharles.Forsyth 		if(p->reg == NREG) {
35274a4d8c2SCharles.Forsyth 			if(p->to.type == D_REG || p->to.type == D_FREG)
35374a4d8c2SCharles.Forsyth 				p->reg = p->to.reg;
35474a4d8c2SCharles.Forsyth 			if(p->reg == NREG)
35574a4d8c2SCharles.Forsyth 				print("botch %P\n", p);
35674a4d8c2SCharles.Forsyth 		}
35774a4d8c2SCharles.Forsyth 		break;
35874a4d8c2SCharles.Forsyth 	}
35974a4d8c2SCharles.Forsyth 
36074a4d8c2SCharles.Forsyth /*
36174a4d8c2SCharles.Forsyth  * flags based on 'to' field
36274a4d8c2SCharles.Forsyth  */
36374a4d8c2SCharles.Forsyth 	c = p->to.class;
36474a4d8c2SCharles.Forsyth 	if(c == 0) {
36574a4d8c2SCharles.Forsyth 		c = aclass(&p->to) + 1;
36674a4d8c2SCharles.Forsyth 		p->to.class = c;
36774a4d8c2SCharles.Forsyth 	}
36874a4d8c2SCharles.Forsyth 	c--;
36974a4d8c2SCharles.Forsyth 	switch(c) {
37074a4d8c2SCharles.Forsyth 	default:
37174a4d8c2SCharles.Forsyth 		print("unknown class %d %D\n", c, &p->to);
37274a4d8c2SCharles.Forsyth 
37374a4d8c2SCharles.Forsyth 	case C_ZCON:
37474a4d8c2SCharles.Forsyth 	case C_SCON:
37574a4d8c2SCharles.Forsyth 	case C_ADD0CON:
37674a4d8c2SCharles.Forsyth 	case C_AND0CON:
37774a4d8c2SCharles.Forsyth 	case C_ADDCON:
37874a4d8c2SCharles.Forsyth 	case C_ANDCON:
37974a4d8c2SCharles.Forsyth 	case C_UCON:
38074a4d8c2SCharles.Forsyth 	case C_LCON:
38174a4d8c2SCharles.Forsyth 	case C_NONE:
38274a4d8c2SCharles.Forsyth 	case C_SBRA:
38374a4d8c2SCharles.Forsyth 	case C_LBRA:
38474a4d8c2SCharles.Forsyth 		break;
38574a4d8c2SCharles.Forsyth 
38674a4d8c2SCharles.Forsyth 	case C_HI:
38774a4d8c2SCharles.Forsyth 	case C_LO:
38874a4d8c2SCharles.Forsyth 		s->set.cc |= E_HILO;
38974a4d8c2SCharles.Forsyth 		break;
39074a4d8c2SCharles.Forsyth 	case C_FCREG:
39174a4d8c2SCharles.Forsyth 		s->set.cc |= E_FCR;
39274a4d8c2SCharles.Forsyth 		break;
39374a4d8c2SCharles.Forsyth 	case C_MREG:
39474a4d8c2SCharles.Forsyth 		s->set.cc |= E_MCR;
39574a4d8c2SCharles.Forsyth 		break;
39674a4d8c2SCharles.Forsyth 	case C_ZOREG:
39774a4d8c2SCharles.Forsyth 	case C_SOREG:
39874a4d8c2SCharles.Forsyth 	case C_LOREG:
39974a4d8c2SCharles.Forsyth 		c = p->to.reg;
40074a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<c;
40174a4d8c2SCharles.Forsyth 		if(ad)
40274a4d8c2SCharles.Forsyth 			break;
40374a4d8c2SCharles.Forsyth 		s->size = sz;
40474a4d8c2SCharles.Forsyth 		s->soffset = regoff(&p->to);
40574a4d8c2SCharles.Forsyth 
40674a4d8c2SCharles.Forsyth 		m = ANYMEM;
40774a4d8c2SCharles.Forsyth 		if(c == REGSB)
40874a4d8c2SCharles.Forsyth 			m = E_MEMSB;
40974a4d8c2SCharles.Forsyth 		if(c == REGSP)
41074a4d8c2SCharles.Forsyth 			m = E_MEMSP;
41174a4d8c2SCharles.Forsyth 
41274a4d8c2SCharles.Forsyth 		if(ar)
41374a4d8c2SCharles.Forsyth 			s->used.cc |= m;
41474a4d8c2SCharles.Forsyth 		else
41574a4d8c2SCharles.Forsyth 			s->set.cc |= m;
41674a4d8c2SCharles.Forsyth 		break;
41774a4d8c2SCharles.Forsyth 	case C_SACON:
41874a4d8c2SCharles.Forsyth 	case C_LACON:
41974a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSP;
42074a4d8c2SCharles.Forsyth 		break;
42174a4d8c2SCharles.Forsyth 	case C_SECON:
42274a4d8c2SCharles.Forsyth 	case C_LECON:
42374a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSB;
42474a4d8c2SCharles.Forsyth 		break;
42574a4d8c2SCharles.Forsyth 	case C_REG:
42674a4d8c2SCharles.Forsyth 		if(ar)
42774a4d8c2SCharles.Forsyth 			s->used.ireg |= 1<<p->to.reg;
42874a4d8c2SCharles.Forsyth 		else
42974a4d8c2SCharles.Forsyth 			s->set.ireg |= 1<<p->to.reg;
43074a4d8c2SCharles.Forsyth 		break;
43174a4d8c2SCharles.Forsyth 	case C_FREG:
43274a4d8c2SCharles.Forsyth 		/* do better -- determine double prec */
43374a4d8c2SCharles.Forsyth 		if(ar) {
43474a4d8c2SCharles.Forsyth 			s->used.freg |= 1<<p->to.reg;
43574a4d8c2SCharles.Forsyth 			s->used.freg |= 1<<(p->to.reg|1);
43674a4d8c2SCharles.Forsyth 		} else {
43774a4d8c2SCharles.Forsyth 			s->set.freg |= 1<<p->to.reg;
43874a4d8c2SCharles.Forsyth 			s->set.freg |= 1<<(p->to.reg|1);
43974a4d8c2SCharles.Forsyth 		}
44074a4d8c2SCharles.Forsyth 		if(ld && p->from.type == D_REG)
44174a4d8c2SCharles.Forsyth 			p->mark |= LOAD;
44274a4d8c2SCharles.Forsyth 		break;
44374a4d8c2SCharles.Forsyth 	case C_SAUTO:
44474a4d8c2SCharles.Forsyth 	case C_LAUTO:
44574a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSP;
44674a4d8c2SCharles.Forsyth 		if(ad)
44774a4d8c2SCharles.Forsyth 			break;
44874a4d8c2SCharles.Forsyth 		s->size = sz;
44974a4d8c2SCharles.Forsyth 		s->soffset = regoff(&p->to);
45074a4d8c2SCharles.Forsyth 
45174a4d8c2SCharles.Forsyth 		if(ar)
45274a4d8c2SCharles.Forsyth 			s->used.cc |= E_MEMSP;
45374a4d8c2SCharles.Forsyth 		else
45474a4d8c2SCharles.Forsyth 			s->set.cc |= E_MEMSP;
45574a4d8c2SCharles.Forsyth 		break;
45674a4d8c2SCharles.Forsyth 	case C_SEXT:
45774a4d8c2SCharles.Forsyth 	case C_LEXT:
45874a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSB;
45974a4d8c2SCharles.Forsyth 		if(ad)
46074a4d8c2SCharles.Forsyth 			break;
46174a4d8c2SCharles.Forsyth 		s->size = sz;
46274a4d8c2SCharles.Forsyth 		s->soffset = regoff(&p->to);
46374a4d8c2SCharles.Forsyth 
46474a4d8c2SCharles.Forsyth 		if(ar)
46574a4d8c2SCharles.Forsyth 			s->used.cc |= E_MEMSB;
46674a4d8c2SCharles.Forsyth 		else
46774a4d8c2SCharles.Forsyth 			s->set.cc |= E_MEMSB;
46874a4d8c2SCharles.Forsyth 		break;
46974a4d8c2SCharles.Forsyth 	}
47074a4d8c2SCharles.Forsyth 
47174a4d8c2SCharles.Forsyth /*
47274a4d8c2SCharles.Forsyth  * flags based on 'from' field
47374a4d8c2SCharles.Forsyth  */
47474a4d8c2SCharles.Forsyth 	c = p->from.class;
47574a4d8c2SCharles.Forsyth 	if(c == 0) {
47674a4d8c2SCharles.Forsyth 		c = aclass(&p->from) + 1;
47774a4d8c2SCharles.Forsyth 		p->from.class = c;
47874a4d8c2SCharles.Forsyth 	}
47974a4d8c2SCharles.Forsyth 	c--;
48074a4d8c2SCharles.Forsyth 	switch(c) {
48174a4d8c2SCharles.Forsyth 	default:
48274a4d8c2SCharles.Forsyth 		print("unknown class %d %D\n", c, &p->from);
48374a4d8c2SCharles.Forsyth 
48474a4d8c2SCharles.Forsyth 	case C_ZCON:
48574a4d8c2SCharles.Forsyth 	case C_SCON:
48674a4d8c2SCharles.Forsyth 	case C_ADD0CON:
48774a4d8c2SCharles.Forsyth 	case C_AND0CON:
48874a4d8c2SCharles.Forsyth 	case C_ADDCON:
48974a4d8c2SCharles.Forsyth 	case C_ANDCON:
49074a4d8c2SCharles.Forsyth 	case C_UCON:
49174a4d8c2SCharles.Forsyth 	case C_LCON:
49274a4d8c2SCharles.Forsyth 	case C_NONE:
49374a4d8c2SCharles.Forsyth 	case C_SBRA:
49474a4d8c2SCharles.Forsyth 	case C_LBRA:
49574a4d8c2SCharles.Forsyth 		break;
49674a4d8c2SCharles.Forsyth 	case C_HI:
49774a4d8c2SCharles.Forsyth 	case C_LO:
49874a4d8c2SCharles.Forsyth 		s->used.cc |= E_HILO;
49974a4d8c2SCharles.Forsyth 		break;
50074a4d8c2SCharles.Forsyth 	case C_FCREG:
50174a4d8c2SCharles.Forsyth 		s->used.cc |= E_FCR;
50274a4d8c2SCharles.Forsyth 		break;
50374a4d8c2SCharles.Forsyth 	case C_MREG:
50474a4d8c2SCharles.Forsyth 		s->used.cc |= E_MCR;
50574a4d8c2SCharles.Forsyth 		break;
50674a4d8c2SCharles.Forsyth 	case C_ZOREG:
50774a4d8c2SCharles.Forsyth 	case C_SOREG:
50874a4d8c2SCharles.Forsyth 	case C_LOREG:
50974a4d8c2SCharles.Forsyth 		c = p->from.reg;
51074a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<c;
51174a4d8c2SCharles.Forsyth 		if(ld)
51274a4d8c2SCharles.Forsyth 			p->mark |= LOAD;
51374a4d8c2SCharles.Forsyth 		s->size = sz;
51474a4d8c2SCharles.Forsyth 		s->soffset = regoff(&p->from);
51574a4d8c2SCharles.Forsyth 
51674a4d8c2SCharles.Forsyth 		m = ANYMEM;
51774a4d8c2SCharles.Forsyth 		if(c == REGSB)
51874a4d8c2SCharles.Forsyth 			m = E_MEMSB;
51974a4d8c2SCharles.Forsyth 		if(c == REGSP)
52074a4d8c2SCharles.Forsyth 			m = E_MEMSP;
52174a4d8c2SCharles.Forsyth 
52274a4d8c2SCharles.Forsyth 		s->used.cc |= m;
52374a4d8c2SCharles.Forsyth 		break;
52474a4d8c2SCharles.Forsyth 	case C_SACON:
52574a4d8c2SCharles.Forsyth 	case C_LACON:
52674a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSP;
52774a4d8c2SCharles.Forsyth 		break;
52874a4d8c2SCharles.Forsyth 	case C_SECON:
52974a4d8c2SCharles.Forsyth 	case C_LECON:
53074a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSB;
53174a4d8c2SCharles.Forsyth 		break;
53274a4d8c2SCharles.Forsyth 	case C_REG:
53374a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<p->from.reg;
53474a4d8c2SCharles.Forsyth 		break;
53574a4d8c2SCharles.Forsyth 	case C_FREG:
53674a4d8c2SCharles.Forsyth 		/* do better -- determine double prec */
53774a4d8c2SCharles.Forsyth 		s->used.freg |= 1<<p->from.reg;
53874a4d8c2SCharles.Forsyth 		s->used.freg |= 1<<(p->from.reg|1);
53974a4d8c2SCharles.Forsyth 		if(ld && p->to.type == D_REG)
54074a4d8c2SCharles.Forsyth 			p->mark |= LOAD;
54174a4d8c2SCharles.Forsyth 		break;
54274a4d8c2SCharles.Forsyth 	case C_SAUTO:
54374a4d8c2SCharles.Forsyth 	case C_LAUTO:
54474a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSP;
54574a4d8c2SCharles.Forsyth 		if(ld)
54674a4d8c2SCharles.Forsyth 			p->mark |= LOAD;
54774a4d8c2SCharles.Forsyth 		if(ad)
54874a4d8c2SCharles.Forsyth 			break;
54974a4d8c2SCharles.Forsyth 		s->size = sz;
55074a4d8c2SCharles.Forsyth 		s->soffset = regoff(&p->from);
55174a4d8c2SCharles.Forsyth 
55274a4d8c2SCharles.Forsyth 		s->used.cc |= E_MEMSP;
55374a4d8c2SCharles.Forsyth 		break;
55474a4d8c2SCharles.Forsyth 	case C_SEXT:
55574a4d8c2SCharles.Forsyth 	case C_LEXT:
55674a4d8c2SCharles.Forsyth 		s->used.ireg |= 1<<REGSB;
55774a4d8c2SCharles.Forsyth 		if(ld)
55874a4d8c2SCharles.Forsyth 			p->mark |= LOAD;
55974a4d8c2SCharles.Forsyth 		if(ad)
56074a4d8c2SCharles.Forsyth 			break;
56174a4d8c2SCharles.Forsyth 		s->size = sz;
56274a4d8c2SCharles.Forsyth 		s->soffset = regoff(&p->from);
56374a4d8c2SCharles.Forsyth 
56474a4d8c2SCharles.Forsyth 		s->used.cc |= E_MEMSB;
56574a4d8c2SCharles.Forsyth 		break;
56674a4d8c2SCharles.Forsyth 	}
56774a4d8c2SCharles.Forsyth 
56874a4d8c2SCharles.Forsyth 	c = p->reg;
56974a4d8c2SCharles.Forsyth 	if(c != NREG) {
57074a4d8c2SCharles.Forsyth 		if(p->from.type == D_FREG || p->to.type == D_FREG) {
57174a4d8c2SCharles.Forsyth 			s->used.freg |= 1<<c;
57274a4d8c2SCharles.Forsyth 			s->used.freg |= 1<<(c|1);
57374a4d8c2SCharles.Forsyth 		} else
57474a4d8c2SCharles.Forsyth 			s->used.ireg |= 1<<c;
57574a4d8c2SCharles.Forsyth 	}
57674a4d8c2SCharles.Forsyth 	s->set.ireg &= ~(1<<REGZERO);		/* R0 cant be set */
57774a4d8c2SCharles.Forsyth }
57874a4d8c2SCharles.Forsyth 
57974a4d8c2SCharles.Forsyth /*
58074a4d8c2SCharles.Forsyth  * test to see if 2 instrictions can be
58174a4d8c2SCharles.Forsyth  * interchanged without changing semantics
58274a4d8c2SCharles.Forsyth  */
58374a4d8c2SCharles.Forsyth int
depend(Sch * sa,Sch * sb)58474a4d8c2SCharles.Forsyth depend(Sch *sa, Sch *sb)
58574a4d8c2SCharles.Forsyth {
58674a4d8c2SCharles.Forsyth 	ulong x;
58774a4d8c2SCharles.Forsyth 
58874a4d8c2SCharles.Forsyth 	if(sa->set.ireg & (sb->set.ireg|sb->used.ireg))
58974a4d8c2SCharles.Forsyth 		return 1;
59074a4d8c2SCharles.Forsyth 	if(sb->set.ireg & sa->used.ireg)
59174a4d8c2SCharles.Forsyth 		return 1;
59274a4d8c2SCharles.Forsyth 
59374a4d8c2SCharles.Forsyth 	if(sa->set.freg & (sb->set.freg|sb->used.freg))
59474a4d8c2SCharles.Forsyth 		return 1;
59574a4d8c2SCharles.Forsyth 	if(sb->set.freg & sa->used.freg)
59674a4d8c2SCharles.Forsyth 		return 1;
59774a4d8c2SCharles.Forsyth 
59874a4d8c2SCharles.Forsyth 	/*
59974a4d8c2SCharles.Forsyth 	 * special case.
60074a4d8c2SCharles.Forsyth 	 * loads from same address cannot pass.
60174a4d8c2SCharles.Forsyth 	 * this is for hardware fifo's and the like
60274a4d8c2SCharles.Forsyth 	 */
60374a4d8c2SCharles.Forsyth 	if(sa->used.cc & sb->used.cc & E_MEM)
60474a4d8c2SCharles.Forsyth 		if(sa->p.reg == sb->p.reg)
60574a4d8c2SCharles.Forsyth 		if(regoff(&sa->p.from) == regoff(&sb->p.from))
60674a4d8c2SCharles.Forsyth 			return 1;
60774a4d8c2SCharles.Forsyth 
60874a4d8c2SCharles.Forsyth 	x = (sa->set.cc & (sb->set.cc|sb->used.cc)) |
60974a4d8c2SCharles.Forsyth 		(sb->set.cc & sa->used.cc);
61074a4d8c2SCharles.Forsyth 	if(x) {
61174a4d8c2SCharles.Forsyth 		/*
61274a4d8c2SCharles.Forsyth 		 * allow SB and SP to pass each other.
61374a4d8c2SCharles.Forsyth 		 * allow SB to pass SB iff doffsets are ok
61474a4d8c2SCharles.Forsyth 		 * anything else conflicts
61574a4d8c2SCharles.Forsyth 		 */
61674a4d8c2SCharles.Forsyth 		if(x != E_MEMSP && x != E_MEMSB)
61774a4d8c2SCharles.Forsyth 			return 1;
61874a4d8c2SCharles.Forsyth 		x = sa->set.cc | sb->set.cc |
61974a4d8c2SCharles.Forsyth 			sa->used.cc | sb->used.cc;
62074a4d8c2SCharles.Forsyth 		if(x & E_MEM)
62174a4d8c2SCharles.Forsyth 			return 1;
62274a4d8c2SCharles.Forsyth 		if(offoverlap(sa, sb))
62374a4d8c2SCharles.Forsyth 			return 1;
62474a4d8c2SCharles.Forsyth 	}
62574a4d8c2SCharles.Forsyth 
62674a4d8c2SCharles.Forsyth 	return 0;
62774a4d8c2SCharles.Forsyth }
62874a4d8c2SCharles.Forsyth 
62974a4d8c2SCharles.Forsyth int
offoverlap(Sch * sa,Sch * sb)63074a4d8c2SCharles.Forsyth offoverlap(Sch *sa, Sch *sb)
63174a4d8c2SCharles.Forsyth {
63274a4d8c2SCharles.Forsyth 
63374a4d8c2SCharles.Forsyth 	if(sa->soffset < sb->soffset) {
63474a4d8c2SCharles.Forsyth 		if(sa->soffset+sa->size > sb->soffset)
63574a4d8c2SCharles.Forsyth 			return 1;
63674a4d8c2SCharles.Forsyth 		return 0;
63774a4d8c2SCharles.Forsyth 	}
63874a4d8c2SCharles.Forsyth 	if(sb->soffset+sb->size > sa->soffset)
63974a4d8c2SCharles.Forsyth 		return 1;
64074a4d8c2SCharles.Forsyth 	return 0;
64174a4d8c2SCharles.Forsyth }
64274a4d8c2SCharles.Forsyth 
64374a4d8c2SCharles.Forsyth /*
64474a4d8c2SCharles.Forsyth  * test 2 adjacent instructions
64574a4d8c2SCharles.Forsyth  * and find out if inserted instructions
64674a4d8c2SCharles.Forsyth  * are desired to prevent stalls.
64774a4d8c2SCharles.Forsyth  */
64874a4d8c2SCharles.Forsyth int
conflict(Sch * sa,Sch * sb)64974a4d8c2SCharles.Forsyth conflict(Sch *sa, Sch *sb)
65074a4d8c2SCharles.Forsyth {
65174a4d8c2SCharles.Forsyth 
65274a4d8c2SCharles.Forsyth 	if(sa->set.ireg & sb->used.ireg)
65374a4d8c2SCharles.Forsyth 		return 1;
65474a4d8c2SCharles.Forsyth 	if(sa->set.freg & sb->used.freg)
65574a4d8c2SCharles.Forsyth 		return 1;
65674a4d8c2SCharles.Forsyth 	if(sa->set.cc & sb->used.cc)
65774a4d8c2SCharles.Forsyth 		return 1;
65874a4d8c2SCharles.Forsyth 
65974a4d8c2SCharles.Forsyth 	return 0;
66074a4d8c2SCharles.Forsyth }
66174a4d8c2SCharles.Forsyth 
66274a4d8c2SCharles.Forsyth int
compound(Prog * p)66374a4d8c2SCharles.Forsyth compound(Prog *p)
66474a4d8c2SCharles.Forsyth {
66574a4d8c2SCharles.Forsyth 	Optab *o;
66674a4d8c2SCharles.Forsyth 
66774a4d8c2SCharles.Forsyth 	o = oplook(p);
66874a4d8c2SCharles.Forsyth 	if(o->size != 4)
66974a4d8c2SCharles.Forsyth 		return 1;
67074a4d8c2SCharles.Forsyth 	if(p->to.type == D_REG && p->to.reg == REGSB)
67174a4d8c2SCharles.Forsyth 		return 1;
67274a4d8c2SCharles.Forsyth 	return 0;
67374a4d8c2SCharles.Forsyth }
67474a4d8c2SCharles.Forsyth 
67574a4d8c2SCharles.Forsyth void
dumpbits(Sch * s,Dep * d)67674a4d8c2SCharles.Forsyth dumpbits(Sch *s, Dep *d)
67774a4d8c2SCharles.Forsyth {
67874a4d8c2SCharles.Forsyth 	int i;
67974a4d8c2SCharles.Forsyth 
68074a4d8c2SCharles.Forsyth 	for(i=0; i<32; i++)
68174a4d8c2SCharles.Forsyth 		if(d->ireg & (1<<i))
68274a4d8c2SCharles.Forsyth 			Bprint(&bso, " R%d", i);
68374a4d8c2SCharles.Forsyth 	for(i=0; i<32; i++)
68474a4d8c2SCharles.Forsyth 		if(d->freg & (1<<i))
68574a4d8c2SCharles.Forsyth 			Bprint(&bso, " F%d", i);
68674a4d8c2SCharles.Forsyth 	for(i=0; i<32; i++)
68774a4d8c2SCharles.Forsyth 		switch(d->cc & (1<<i)) {
68874a4d8c2SCharles.Forsyth 		default:
68974a4d8c2SCharles.Forsyth 			break;
69074a4d8c2SCharles.Forsyth 		case E_HILO:
69174a4d8c2SCharles.Forsyth 			Bprint(&bso, " HILO");
69274a4d8c2SCharles.Forsyth 			break;
69374a4d8c2SCharles.Forsyth 		case E_FCR:
69474a4d8c2SCharles.Forsyth 			Bprint(&bso, " FCR");
69574a4d8c2SCharles.Forsyth 			break;
69674a4d8c2SCharles.Forsyth 		case E_MCR:
69774a4d8c2SCharles.Forsyth 			Bprint(&bso, " MCR");
69874a4d8c2SCharles.Forsyth 			break;
69974a4d8c2SCharles.Forsyth 		case E_MEM:
70074a4d8c2SCharles.Forsyth 			Bprint(&bso, " MEM%d", s->size);
70174a4d8c2SCharles.Forsyth 			break;
70274a4d8c2SCharles.Forsyth 		case E_MEMSB:
70374a4d8c2SCharles.Forsyth 			Bprint(&bso, " SB%d", s->size);
70474a4d8c2SCharles.Forsyth 			break;
70574a4d8c2SCharles.Forsyth 		case E_MEMSP:
70674a4d8c2SCharles.Forsyth 			Bprint(&bso, " SP%d", s->size);
70774a4d8c2SCharles.Forsyth 			break;
70874a4d8c2SCharles.Forsyth 		}
70974a4d8c2SCharles.Forsyth }
710