xref: /plan9/sys/src/cmd/kl/sched.c (revision 375daca8932d0755549a5f8e4d068a24a49927d4)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier enum
43e12c5d1SDavid du Colombier {
5bd389b36SDavid du Colombier 	E_ICC	= 1<<0,
6bd389b36SDavid du Colombier 	E_FCC	= 1<<1,
7bd389b36SDavid du Colombier 	E_MEM	= 1<<2,
8bd389b36SDavid du Colombier 	E_MEMSP	= 1<<3,	/* uses offset and size */
9bd389b36SDavid du Colombier 	E_MEMSB	= 1<<4,	/* uses offset and size */
10bd389b36SDavid du Colombier 	ANYMEM	= E_MEM|E_MEMSP|E_MEMSB,
11*375daca8SDavid du Colombier 	ALL	= ~0
123e12c5d1SDavid du Colombier };
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier typedef	struct	Sch	Sch;
15bd389b36SDavid du Colombier typedef	struct	Dep	Dep;
16bd389b36SDavid du Colombier 
17bd389b36SDavid du Colombier struct	Dep
18bd389b36SDavid du Colombier {
19bd389b36SDavid du Colombier 	ulong	ireg;
20bd389b36SDavid du Colombier 	ulong	freg;
21bd389b36SDavid du Colombier 	ulong	cc;
22bd389b36SDavid du Colombier };
233e12c5d1SDavid du Colombier struct	Sch
243e12c5d1SDavid du Colombier {
253e12c5d1SDavid du Colombier 	Prog	p;
26bd389b36SDavid du Colombier 	Dep	set;
27bd389b36SDavid du Colombier 	Dep	used;
287dd7cddfSDavid du Colombier 	long	soffset;
29bd389b36SDavid du Colombier 	char	size;
303e12c5d1SDavid du Colombier 	char	nop;
313e12c5d1SDavid du Colombier 	char	comp;
323e12c5d1SDavid du Colombier };
333e12c5d1SDavid du Colombier 
347dd7cddfSDavid du Colombier void	regsused(Sch*, Prog*);
35bd389b36SDavid du Colombier int	depend(Sch*, Sch*);
36bd389b36SDavid du Colombier int	conflict(Sch*, Sch*);
37bd389b36SDavid du Colombier int	offoverlap(Sch*, Sch*);
38bd389b36SDavid du Colombier void	dumpbits(Sch*, Dep*);
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier void
sched(Prog * p0,Prog * pe)413e12c5d1SDavid du Colombier sched(Prog *p0, Prog *pe)
423e12c5d1SDavid du Colombier {
433e12c5d1SDavid du Colombier 	Prog *p, *q;
443e12c5d1SDavid du Colombier 	Sch sch[NSCHED], *s, *t, *u, *se, stmp;
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	/*
473e12c5d1SDavid du Colombier 	 * build side structure
483e12c5d1SDavid du Colombier 	 */
493e12c5d1SDavid du Colombier 	s = sch;
503e12c5d1SDavid du Colombier 	for(p=p0;; p=p->link) {
51bd389b36SDavid du Colombier 		memset(s, 0, sizeof(*s));
523e12c5d1SDavid du Colombier 		s->p = *p;
537dd7cddfSDavid du Colombier 		regsused(s, p);
54bd389b36SDavid du Colombier 		if(debug['X']) {
55bd389b36SDavid du Colombier 			Bprint(&bso, "%P\tset", &s->p);
56bd389b36SDavid du Colombier 			dumpbits(s, &s->set);
57bd389b36SDavid du Colombier 			Bprint(&bso, "; used");
58bd389b36SDavid du Colombier 			dumpbits(s, &s->used);
59219b2ee8SDavid du Colombier 			if(s->comp)
60219b2ee8SDavid du Colombier 				Bprint(&bso, "; compound");
61219b2ee8SDavid du Colombier 			if(s->p.mark & LOAD)
62219b2ee8SDavid du Colombier 				Bprint(&bso, "; load");
63219b2ee8SDavid du Colombier 			if(s->p.mark & BRANCH)
64219b2ee8SDavid du Colombier 				Bprint(&bso, "; branch");
65219b2ee8SDavid du Colombier 			if(s->p.mark & FCMP)
66219b2ee8SDavid du Colombier 				Bprint(&bso, "; fcmp");
67bd389b36SDavid du Colombier 			Bprint(&bso, "\n");
68bd389b36SDavid du Colombier 		}
693e12c5d1SDavid du Colombier 		s++;
703e12c5d1SDavid du Colombier 		if(p == pe)
713e12c5d1SDavid du Colombier 			break;
723e12c5d1SDavid du Colombier 	}
733e12c5d1SDavid du Colombier 	se = s;
743e12c5d1SDavid du Colombier 
753e12c5d1SDavid du Colombier 	for(s=se-1; s>=sch; s--) {
763e12c5d1SDavid du Colombier 		/*
773e12c5d1SDavid du Colombier 		 * branch delay slot
783e12c5d1SDavid du Colombier 		 */
793e12c5d1SDavid du Colombier 		if(s->p.mark & BRANCH) {
803e12c5d1SDavid du Colombier 			/* t is the trial instruction to use */
813e12c5d1SDavid du Colombier 			for(t=s-1; t>=sch; t--) {
823e12c5d1SDavid du Colombier 				if(t->comp || (t->p.mark & FCMP))
833e12c5d1SDavid du Colombier 					goto no1;
843e12c5d1SDavid du Colombier 				for(u=t+1; u<=s; u++)
85bd389b36SDavid du Colombier 					if(depend(u, t))
863e12c5d1SDavid du Colombier 						goto no1;
873e12c5d1SDavid du Colombier 				goto out1;
883e12c5d1SDavid du Colombier 			no1:;
893e12c5d1SDavid du Colombier 			}
903e12c5d1SDavid du Colombier 			if(debug['X'])
913e12c5d1SDavid du Colombier 				Bprint(&bso, "?b%P\n", &s->p);
923e12c5d1SDavid du Colombier 			s->nop = 1;
933e12c5d1SDavid du Colombier 			continue;
943e12c5d1SDavid du Colombier 
953e12c5d1SDavid du Colombier 		out1:
963e12c5d1SDavid du Colombier 			if(debug['X']) {
973e12c5d1SDavid du Colombier 				Bprint(&bso, "!b%P\n", &t->p);
983e12c5d1SDavid du Colombier 				Bprint(&bso, "%P\n", &s->p);
993e12c5d1SDavid du Colombier 			}
1003e12c5d1SDavid du Colombier 			stmp = *t;
1013e12c5d1SDavid du Colombier 			memmove(t, t+1, (uchar*)s - (uchar*)t);
1023e12c5d1SDavid du Colombier 			*s = stmp;
1033e12c5d1SDavid du Colombier 			s--;
1043e12c5d1SDavid du Colombier 			continue;
1053e12c5d1SDavid du Colombier 		}
1063e12c5d1SDavid du Colombier 
1073e12c5d1SDavid du Colombier 		/*
1083e12c5d1SDavid du Colombier 		 * load delay. interlocked.
1093e12c5d1SDavid du Colombier 		 */
1103e12c5d1SDavid du Colombier 		if(s->p.mark & LOAD) {
1113e12c5d1SDavid du Colombier 			if(s >= se-1)
1123e12c5d1SDavid du Colombier 				continue;
113bd389b36SDavid du Colombier 			if(!conflict(s, (s+1)))
1143e12c5d1SDavid du Colombier 				continue;
115bd389b36SDavid du Colombier 			/*
116bd389b36SDavid du Colombier 			 * s is load, s+1 is immediate use of result
117bd389b36SDavid du Colombier 			 * t is the trial instruction to insert between s and s+1
118bd389b36SDavid du Colombier 			 */
1193e12c5d1SDavid du Colombier 			for(t=s-1; t>=sch; t--) {
1203e12c5d1SDavid du Colombier 				if(t->p.mark & BRANCH)
1213e12c5d1SDavid du Colombier 					goto no2;
1223e12c5d1SDavid du Colombier 				if(t->p.mark & FCMP)
1233e12c5d1SDavid du Colombier 					if((s+1)->p.mark & BRANCH)
1243e12c5d1SDavid du Colombier 						goto no2;
1253e12c5d1SDavid du Colombier 				if(t->p.mark & LOAD)
126bd389b36SDavid du Colombier 					if(conflict(t, (s+1)))
1273e12c5d1SDavid du Colombier 						goto no2;
1283e12c5d1SDavid du Colombier 				for(u=t+1; u<=s; u++)
129bd389b36SDavid du Colombier 					if(depend(u, t))
1303e12c5d1SDavid du Colombier 						goto no2;
1313e12c5d1SDavid du Colombier 				goto out2;
1323e12c5d1SDavid du Colombier 			no2:;
1333e12c5d1SDavid du Colombier 			}
1343e12c5d1SDavid du Colombier 			if(debug['X'])
1353e12c5d1SDavid du Colombier 				Bprint(&bso, "?l%P\n", &s->p);
1363e12c5d1SDavid du Colombier 			continue;
1373e12c5d1SDavid du Colombier 		out2:
1383e12c5d1SDavid du Colombier 			if(debug['X']) {
1393e12c5d1SDavid du Colombier 				Bprint(&bso, "!l%P\n", &t->p);
1403e12c5d1SDavid du Colombier 				Bprint(&bso, "%P\n", &s->p);
1413e12c5d1SDavid du Colombier 			}
1423e12c5d1SDavid du Colombier 			stmp = *t;
1433e12c5d1SDavid du Colombier 			memmove(t, t+1, (uchar*)s - (uchar*)t);
1443e12c5d1SDavid du Colombier 			*s = stmp;
1453e12c5d1SDavid du Colombier 			s--;
1463e12c5d1SDavid du Colombier 			continue;
1473e12c5d1SDavid du Colombier 		}
1483e12c5d1SDavid du Colombier 
1493e12c5d1SDavid du Colombier 		/*
1503e12c5d1SDavid du Colombier 		 * fop2 delay.
1513e12c5d1SDavid du Colombier 		 */
1523e12c5d1SDavid du Colombier 		if(s->p.mark & FCMP) {
1533e12c5d1SDavid du Colombier 			if(s >= se-1) {
1543e12c5d1SDavid du Colombier 				s->nop = 1;
1553e12c5d1SDavid du Colombier 				continue;
1563e12c5d1SDavid du Colombier 			}
1573e12c5d1SDavid du Colombier 			if(!((s+1)->p.mark & BRANCH))
1583e12c5d1SDavid du Colombier 				continue;
1593e12c5d1SDavid du Colombier 			/* t is the trial instruction to use */
1603e12c5d1SDavid du Colombier 			for(t=s-1; t>=sch; t--) {
1613e12c5d1SDavid du Colombier 				for(u=t+1; u<=s; u++)
162bd389b36SDavid du Colombier 					if(depend(u, t))
1633e12c5d1SDavid du Colombier 						goto no3;
1643e12c5d1SDavid du Colombier 				goto out3;
1653e12c5d1SDavid du Colombier 			no3:;
1663e12c5d1SDavid du Colombier 			}
1673e12c5d1SDavid du Colombier 			if(debug['X'])
1683e12c5d1SDavid du Colombier 				Bprint(&bso, "?f%P\n", &s->p);
1693e12c5d1SDavid du Colombier 			s->nop = 1;
1703e12c5d1SDavid du Colombier 			continue;
1713e12c5d1SDavid du Colombier 		out3:
1723e12c5d1SDavid du Colombier 			if(debug['X']) {
1733e12c5d1SDavid du Colombier 				Bprint(&bso, "!f%P\n", &t->p);
1743e12c5d1SDavid du Colombier 				Bprint(&bso, "%P\n", &s->p);
1753e12c5d1SDavid du Colombier 			}
1763e12c5d1SDavid du Colombier 			stmp = *t;
1773e12c5d1SDavid du Colombier 			memmove(t, t+1, (uchar*)s - (uchar*)t);
1783e12c5d1SDavid du Colombier 			*s = stmp;
1793e12c5d1SDavid du Colombier 			s--;
1803e12c5d1SDavid du Colombier 			continue;
1813e12c5d1SDavid du Colombier 		}
1823e12c5d1SDavid du Colombier 	}
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier 	/*
1853e12c5d1SDavid du Colombier 	 * put it all back
1863e12c5d1SDavid du Colombier 	 */
1873e12c5d1SDavid du Colombier 	for(s=sch, p=p0; s<se; s++, p=q) {
1883e12c5d1SDavid du Colombier 		q = p->link;
1893e12c5d1SDavid du Colombier 		if(q != s->p.link) {
1903e12c5d1SDavid du Colombier 			*p = s->p;
1913e12c5d1SDavid du Colombier 			p->link = q;
1923e12c5d1SDavid du Colombier 		}
1933e12c5d1SDavid du Colombier 		if(s->nop)
1943e12c5d1SDavid du Colombier 			addnop(p);
1953e12c5d1SDavid du Colombier 	}
1963e12c5d1SDavid du Colombier 	if(debug['X'])
1973e12c5d1SDavid du Colombier 		Bprint(&bso, "\n");
1983e12c5d1SDavid du Colombier }
1993e12c5d1SDavid du Colombier 
200bd389b36SDavid du Colombier void
regsused(Sch * s,Prog * realp)2017dd7cddfSDavid du Colombier regsused(Sch *s, Prog *realp)
2023e12c5d1SDavid du Colombier {
203bd389b36SDavid du Colombier 	int c, ar, ad, ld, sz;
204bd389b36SDavid du Colombier 	ulong m;
205bd389b36SDavid du Colombier 	Prog *p;
2063e12c5d1SDavid du Colombier 
207bd389b36SDavid du Colombier 	p = &s->p;
208bd389b36SDavid du Colombier 	s->comp = compound(p);
209bd389b36SDavid du Colombier 	s->nop = 0;
210219b2ee8SDavid du Colombier 	if(s->comp) {
211219b2ee8SDavid du Colombier 		s->set.ireg |= 1<<REGTMP;
212219b2ee8SDavid du Colombier 		s->used.ireg |= 1<<REGTMP;
213219b2ee8SDavid du Colombier 	}
2143e12c5d1SDavid du Colombier 	ar = 0;		/* dest is really reference */
215bd389b36SDavid du Colombier 	ad = 0;		/* source/dest is really address */
2163e12c5d1SDavid du Colombier 	ld = 0;		/* opcode is load instruction */
217bd389b36SDavid du Colombier 	sz = 20;		/* size of load/store for overlap computation */
2183e12c5d1SDavid du Colombier 
219bd389b36SDavid du Colombier /*
220bd389b36SDavid du Colombier  * flags based on opcode
221bd389b36SDavid du Colombier  */
2223e12c5d1SDavid du Colombier 	switch(p->as) {
2233e12c5d1SDavid du Colombier 	case ATEXT:
224219b2ee8SDavid du Colombier 		curtext = realp;
2253e12c5d1SDavid du Colombier 		autosize = p->to.offset + 4;
226bd389b36SDavid du Colombier 		ad = 1;
2273e12c5d1SDavid du Colombier 		break;
2283e12c5d1SDavid du Colombier 	case AJMPL:
2293e12c5d1SDavid du Colombier 		c = p->reg;
2303e12c5d1SDavid du Colombier 		if(c == NREG)
2313e12c5d1SDavid du Colombier 			c = REGLINK;
232bd389b36SDavid du Colombier 		s->set.ireg |= 1<<c;
2333e12c5d1SDavid du Colombier 		ar = 1;
234bd389b36SDavid du Colombier 		ad = 1;
2353e12c5d1SDavid du Colombier 		break;
2363e12c5d1SDavid du Colombier 	case AJMP:
2373e12c5d1SDavid du Colombier 		ar = 1;
2383e12c5d1SDavid du Colombier 		ad = 1;
2393e12c5d1SDavid du Colombier 		break;
2403e12c5d1SDavid du Colombier 	case ACMP:
241bd389b36SDavid du Colombier 		s->set.cc |= E_ICC;
2423e12c5d1SDavid du Colombier 		ar = 1;
2433e12c5d1SDavid du Colombier 		break;
2443e12c5d1SDavid du Colombier 	case AFCMPD:
2453e12c5d1SDavid du Colombier 	case AFCMPED:
2463e12c5d1SDavid du Colombier 	case AFCMPEF:
2473e12c5d1SDavid du Colombier 	case AFCMPEX:
2483e12c5d1SDavid du Colombier 	case AFCMPF:
2493e12c5d1SDavid du Colombier 	case AFCMPX:
250bd389b36SDavid du Colombier 		s->set.cc |= E_FCC;
2513e12c5d1SDavid du Colombier 		ar = 1;
2523e12c5d1SDavid du Colombier 		break;
2533e12c5d1SDavid du Colombier 	case ABE:
2543e12c5d1SDavid du Colombier 	case ABNE:
2553e12c5d1SDavid du Colombier 	case ABLE:
2563e12c5d1SDavid du Colombier 	case ABG:
2573e12c5d1SDavid du Colombier 	case ABL:
2583e12c5d1SDavid du Colombier 	case ABGE:
2593e12c5d1SDavid du Colombier 	case ABLEU:
2603e12c5d1SDavid du Colombier 	case ABGU:
2613e12c5d1SDavid du Colombier 	case ABCS:
2623e12c5d1SDavid du Colombier 	case ABCC:
2633e12c5d1SDavid du Colombier 	case ABNEG:
2643e12c5d1SDavid du Colombier 	case ABPOS:
2653e12c5d1SDavid du Colombier 	case ABVC:
2663e12c5d1SDavid du Colombier 	case ABVS:
267bd389b36SDavid du Colombier 		s->used.cc |= E_ICC;
2683e12c5d1SDavid du Colombier 		ar = 1;
2693e12c5d1SDavid du Colombier 		break;
2703e12c5d1SDavid du Colombier 	case AFBE:
2713e12c5d1SDavid du Colombier 	case AFBLG:
2723e12c5d1SDavid du Colombier 	case AFBG:
2733e12c5d1SDavid du Colombier 	case AFBLE:
2743e12c5d1SDavid du Colombier 	case AFBGE:
2753e12c5d1SDavid du Colombier 	case AFBL:
276bd389b36SDavid du Colombier 		s->used.cc |= E_FCC;
2773e12c5d1SDavid du Colombier 		ar = 1;
2783e12c5d1SDavid du Colombier 		break;
2793e12c5d1SDavid du Colombier 	case AMOVB:
2803e12c5d1SDavid du Colombier 	case AMOVBU:
281bd389b36SDavid du Colombier 		sz = 1;
282bd389b36SDavid du Colombier 		ld = 1;
283bd389b36SDavid du Colombier 		break;
2843e12c5d1SDavid du Colombier 	case AMOVH:
2853e12c5d1SDavid du Colombier 	case AMOVHU:
286bd389b36SDavid du Colombier 		sz = 2;
2873e12c5d1SDavid du Colombier 		ld = 1;
2883e12c5d1SDavid du Colombier 		break;
289bd389b36SDavid du Colombier 	case AFMOVF:
290bd389b36SDavid du Colombier 	case AMOVW:
291bd389b36SDavid du Colombier 		sz = 4;
292bd389b36SDavid du Colombier 		ld = 1;
293bd389b36SDavid du Colombier 		break;
294bd389b36SDavid du Colombier 	case AMOVD:
295bd389b36SDavid du Colombier 	case AFMOVD:
296bd389b36SDavid du Colombier 		sz = 8;
297bd389b36SDavid du Colombier 		ld = 1;
298bd389b36SDavid du Colombier 		break;
299bd389b36SDavid du Colombier 	case AFMOVX:	/* gok */
300bd389b36SDavid du Colombier 		sz = 16;
301bd389b36SDavid du Colombier 		ld = 1;
302bd389b36SDavid du Colombier 		break;
303bd389b36SDavid du Colombier 	case AADDCC:
304bd389b36SDavid du Colombier 	case AADDXCC:
305bd389b36SDavid du Colombier 	case AANDCC:
306bd389b36SDavid du Colombier 	case AANDNCC:
307bd389b36SDavid du Colombier 	case AORCC:
308bd389b36SDavid du Colombier 	case AORNCC:
309bd389b36SDavid du Colombier 	case ASUBCC:
310bd389b36SDavid du Colombier 	case ASUBXCC:
311bd389b36SDavid du Colombier 	case ATADDCC:
312bd389b36SDavid du Colombier 	case ATADDCCTV:
313bd389b36SDavid du Colombier 	case ATSUBCC:
314bd389b36SDavid du Colombier 	case ATSUBCCTV:
315bd389b36SDavid du Colombier 	case AXNORCC:
316bd389b36SDavid du Colombier 	case AXORCC:
317bd389b36SDavid du Colombier 		s->set.cc |= E_ICC;
318bd389b36SDavid du Colombier 		break;
3193e12c5d1SDavid du Colombier 	case ADIV:
3203e12c5d1SDavid du Colombier 	case ADIVL:
3213e12c5d1SDavid du Colombier 	case AMOD:
3223e12c5d1SDavid du Colombier 	case AMODL:
3233e12c5d1SDavid du Colombier 	case AMUL:
3243e12c5d1SDavid du Colombier 	case AMULSCC:
325bd389b36SDavid du Colombier 	case ATAS:
326bd389b36SDavid du Colombier 		s->set.ireg = ALL;
327bd389b36SDavid du Colombier 		s->set.freg = ALL;
328bd389b36SDavid du Colombier 		s->set.cc = ALL;
3293e12c5d1SDavid du Colombier 		break;
3303e12c5d1SDavid du Colombier 	}
3313e12c5d1SDavid du Colombier 
332bd389b36SDavid du Colombier /*
333bd389b36SDavid du Colombier  * flags based on 'to' field
334bd389b36SDavid du Colombier  */
3353e12c5d1SDavid du Colombier 	c = p->to.class;
3363e12c5d1SDavid du Colombier 	if(c == 0) {
3373e12c5d1SDavid du Colombier 		c = aclass(&p->to) + 1;
3383e12c5d1SDavid du Colombier 		p->to.class = c;
3393e12c5d1SDavid du Colombier 	}
3403e12c5d1SDavid du Colombier 	c--;
3413e12c5d1SDavid du Colombier 	switch(c) {
3423e12c5d1SDavid du Colombier 	default:
3433e12c5d1SDavid du Colombier 		print("unknown class %d %D\n", c, &p->to);
3443e12c5d1SDavid du Colombier 
3453e12c5d1SDavid du Colombier 	case C_ZCON:
3463e12c5d1SDavid du Colombier 	case C_SCON:
3473e12c5d1SDavid du Colombier 	case C_UCON:
3483e12c5d1SDavid du Colombier 	case C_LCON:
3493e12c5d1SDavid du Colombier 	case C_NONE:
3503e12c5d1SDavid du Colombier 	case C_SBRA:
3513e12c5d1SDavid du Colombier 	case C_LBRA:
3523e12c5d1SDavid du Colombier 		break;
3533e12c5d1SDavid du Colombier 	case C_CREG:
3543e12c5d1SDavid du Colombier 	case C_FSR:
3553e12c5d1SDavid du Colombier 	case C_FQ:
3563e12c5d1SDavid du Colombier 	case C_PREG:
357bd389b36SDavid du Colombier 		s->set.ireg = ALL;
358bd389b36SDavid du Colombier 		s->set.freg = ALL;
359bd389b36SDavid du Colombier 		s->set.cc = ALL;
3603e12c5d1SDavid du Colombier 		break;
3613e12c5d1SDavid du Colombier 	case C_ZOREG:
3623e12c5d1SDavid du Colombier 	case C_SOREG:
3633e12c5d1SDavid du Colombier 	case C_LOREG:
3643e12c5d1SDavid du Colombier 	case C_ASI:
365bd389b36SDavid du Colombier 		c = p->to.reg;
366bd389b36SDavid du Colombier 		s->used.ireg |= 1<<c;
367bd389b36SDavid du Colombier 		if(ad)
368bd389b36SDavid du Colombier 			break;
369bd389b36SDavid du Colombier 		s->size = sz;
3707dd7cddfSDavid du Colombier 		s->soffset = regoff(&p->to);
371bd389b36SDavid du Colombier 
372bd389b36SDavid du Colombier 		m = ANYMEM;
373bd389b36SDavid du Colombier 		if(c == REGSB)
374bd389b36SDavid du Colombier 			m = E_MEMSB;
375bd389b36SDavid du Colombier 		if(c == REGSP)
376bd389b36SDavid du Colombier 			m = E_MEMSP;
377bd389b36SDavid du Colombier 
378bd389b36SDavid du Colombier 		if(ar)
379bd389b36SDavid du Colombier 			s->used.cc |= m;
380bd389b36SDavid du Colombier 		else
381bd389b36SDavid du Colombier 			s->set.cc |= m;
3823e12c5d1SDavid du Colombier 		break;
3833e12c5d1SDavid du Colombier 	case C_SACON:
3843e12c5d1SDavid du Colombier 	case C_LACON:
385219b2ee8SDavid du Colombier 		s->used.ireg |= 1<<REGSP;
3863e12c5d1SDavid du Colombier 		break;
3873e12c5d1SDavid du Colombier 	case C_SECON:
3883e12c5d1SDavid du Colombier 	case C_LECON:
389219b2ee8SDavid du Colombier 		s->used.ireg |= 1<<REGSB;
3903e12c5d1SDavid du Colombier 		break;
3913e12c5d1SDavid du Colombier 	case C_REG:
3923e12c5d1SDavid du Colombier 		if(ar)
393bd389b36SDavid du Colombier 			s->used.ireg |= 1<<p->to.reg;
3943e12c5d1SDavid du Colombier 		else
395bd389b36SDavid du Colombier 			s->set.ireg |= 1<<p->to.reg;
3963e12c5d1SDavid du Colombier 		break;
3973e12c5d1SDavid du Colombier 	case C_FREG:
398bd389b36SDavid du Colombier 		/* do better -- determine double prec */
399bd389b36SDavid du Colombier 		if(ar) {
400bd389b36SDavid du Colombier 			s->used.freg |= 1<<p->to.reg;
401bd389b36SDavid du Colombier 			s->used.freg |= 1<<(p->to.reg|1);
402bd389b36SDavid du Colombier 		} else {
403bd389b36SDavid du Colombier 			s->set.freg |= 1<<p->to.reg;
404bd389b36SDavid du Colombier 			s->set.freg |= 1<<(p->to.reg|1);
405bd389b36SDavid du Colombier 		}
4063e12c5d1SDavid du Colombier 		break;
4073e12c5d1SDavid du Colombier 	case C_SAUTO:
4083e12c5d1SDavid du Colombier 	case C_LAUTO:
4093e12c5d1SDavid du Colombier 	case C_ESAUTO:
4103e12c5d1SDavid du Colombier 	case C_OSAUTO:
4113e12c5d1SDavid du Colombier 	case C_ELAUTO:
4123e12c5d1SDavid du Colombier 	case C_OLAUTO:
413bd389b36SDavid du Colombier 		s->used.ireg |= 1<<REGSP;
414bd389b36SDavid du Colombier 		if(ad)
415bd389b36SDavid du Colombier 			break;
416bd389b36SDavid du Colombier 		s->size = sz;
4177dd7cddfSDavid du Colombier 		s->soffset = regoff(&p->to);
418bd389b36SDavid du Colombier 
419bd389b36SDavid du Colombier 		if(ar)
420bd389b36SDavid du Colombier 			s->used.cc |= E_MEMSP;
421bd389b36SDavid du Colombier 		else
422bd389b36SDavid du Colombier 			s->set.cc |= E_MEMSP;
4233e12c5d1SDavid du Colombier 		break;
4243e12c5d1SDavid du Colombier 	case C_SEXT:
4253e12c5d1SDavid du Colombier 	case C_LEXT:
4263e12c5d1SDavid du Colombier 	case C_ESEXT:
4273e12c5d1SDavid du Colombier 	case C_OSEXT:
4283e12c5d1SDavid du Colombier 	case C_ELEXT:
4293e12c5d1SDavid du Colombier 	case C_OLEXT:
430bd389b36SDavid du Colombier 		s->used.ireg |= 1<<REGSB;
431bd389b36SDavid du Colombier 		if(ad)
432bd389b36SDavid du Colombier 			break;
433bd389b36SDavid du Colombier 		s->size = sz;
4347dd7cddfSDavid du Colombier 		s->soffset = regoff(&p->to);
435bd389b36SDavid du Colombier 
436bd389b36SDavid du Colombier 		if(ar)
437bd389b36SDavid du Colombier 			s->used.cc |= E_MEMSB;
438bd389b36SDavid du Colombier 		else
439bd389b36SDavid du Colombier 			s->set.cc |= E_MEMSB;
4403e12c5d1SDavid du Colombier 		break;
4413e12c5d1SDavid du Colombier 	}
4423e12c5d1SDavid du Colombier 
443bd389b36SDavid du Colombier /*
444bd389b36SDavid du Colombier  * flags based on 'from' field
445bd389b36SDavid du Colombier  */
4463e12c5d1SDavid du Colombier 	c = p->from.class;
4473e12c5d1SDavid du Colombier 	if(c == 0) {
4483e12c5d1SDavid du Colombier 		c = aclass(&p->from) + 1;
4493e12c5d1SDavid du Colombier 		p->from.class = c;
4503e12c5d1SDavid du Colombier 	}
4513e12c5d1SDavid du Colombier 	c--;
4523e12c5d1SDavid du Colombier 	switch(c) {
4533e12c5d1SDavid du Colombier 	default:
4543e12c5d1SDavid du Colombier 		print("unknown class %d %D\n", c, &p->from);
4553e12c5d1SDavid du Colombier 
4563e12c5d1SDavid du Colombier 	case C_ZCON:
4573e12c5d1SDavid du Colombier 	case C_SCON:
4583e12c5d1SDavid du Colombier 	case C_UCON:
4593e12c5d1SDavid du Colombier 	case C_LCON:
4603e12c5d1SDavid du Colombier 	case C_NONE:
4613e12c5d1SDavid du Colombier 	case C_SBRA:
4623e12c5d1SDavid du Colombier 	case C_LBRA:
463219b2ee8SDavid du Colombier 		c = p->from.reg;
464219b2ee8SDavid du Colombier 		if(c != NREG)
465219b2ee8SDavid du Colombier 			s->used.ireg |= 1<<c;
4663e12c5d1SDavid du Colombier 		break;
4673e12c5d1SDavid du Colombier 	case C_CREG:
4683e12c5d1SDavid du Colombier 	case C_FSR:
4693e12c5d1SDavid du Colombier 	case C_FQ:
4703e12c5d1SDavid du Colombier 	case C_PREG:
471bd389b36SDavid du Colombier 		s->set.ireg = ALL;
472bd389b36SDavid du Colombier 		s->set.freg = ALL;
473bd389b36SDavid du Colombier 		s->set.cc = ALL;
4743e12c5d1SDavid du Colombier 		break;
4753e12c5d1SDavid du Colombier 	case C_ZOREG:
4763e12c5d1SDavid du Colombier 	case C_SOREG:
4773e12c5d1SDavid du Colombier 	case C_LOREG:
4783e12c5d1SDavid du Colombier 	case C_ASI:
479bd389b36SDavid du Colombier 		c = p->from.reg;
480bd389b36SDavid du Colombier 		s->used.ireg |= 1<<c;
4813e12c5d1SDavid du Colombier 		if(ld)
4823e12c5d1SDavid du Colombier 			p->mark |= LOAD;
483bd389b36SDavid du Colombier 		if(ad)
484bd389b36SDavid du Colombier 			break;
485bd389b36SDavid du Colombier 		s->size = sz;
4867dd7cddfSDavid du Colombier 		s->soffset = regoff(&p->from);
487bd389b36SDavid du Colombier 
488bd389b36SDavid du Colombier 		m = ANYMEM;
489bd389b36SDavid du Colombier 		if(c == REGSB)
490bd389b36SDavid du Colombier 			m = E_MEMSB;
491bd389b36SDavid du Colombier 		if(c == REGSP)
492bd389b36SDavid du Colombier 			m = E_MEMSP;
493bd389b36SDavid du Colombier 
494bd389b36SDavid du Colombier 		s->used.cc |= m;
4953e12c5d1SDavid du Colombier 		break;
4963e12c5d1SDavid du Colombier 	case C_SACON:
4973e12c5d1SDavid du Colombier 	case C_LACON:
498bd389b36SDavid du Colombier 		s->used.ireg |= 1<<REGSP;
4993e12c5d1SDavid du Colombier 		break;
5003e12c5d1SDavid du Colombier 	case C_SECON:
5013e12c5d1SDavid du Colombier 	case C_LECON:
502bd389b36SDavid du Colombier 		s->used.ireg |= 1<<REGSB;
5033e12c5d1SDavid du Colombier 		break;
5043e12c5d1SDavid du Colombier 	case C_REG:
505bd389b36SDavid du Colombier 		s->used.ireg |= 1<<p->from.reg;
5063e12c5d1SDavid du Colombier 		break;
5073e12c5d1SDavid du Colombier 	case C_FREG:
508bd389b36SDavid du Colombier 		/* do better -- determine double prec */
509bd389b36SDavid du Colombier 		s->used.freg |= 1<<p->from.reg;
510bd389b36SDavid du Colombier 		s->used.freg |= 1<<(p->from.reg|1);
5113e12c5d1SDavid du Colombier 		break;
5123e12c5d1SDavid du Colombier 	case C_SAUTO:
5133e12c5d1SDavid du Colombier 	case C_LAUTO:
5143e12c5d1SDavid du Colombier 	case C_ESAUTO:
5153e12c5d1SDavid du Colombier 	case C_ELAUTO:
5163e12c5d1SDavid du Colombier 	case C_OSAUTO:
5173e12c5d1SDavid du Colombier 	case C_OLAUTO:
518bd389b36SDavid du Colombier 		s->used.ireg |= 1<<REGSP;
5193e12c5d1SDavid du Colombier 		if(ld)
5203e12c5d1SDavid du Colombier 			p->mark |= LOAD;
521bd389b36SDavid du Colombier 		if(ad)
522bd389b36SDavid du Colombier 			break;
523bd389b36SDavid du Colombier 		s->size = sz;
5247dd7cddfSDavid du Colombier 		s->soffset = regoff(&p->from);
525bd389b36SDavid du Colombier 
526bd389b36SDavid du Colombier 		s->used.cc |= E_MEMSP;
5273e12c5d1SDavid du Colombier 		break;
5283e12c5d1SDavid du Colombier 	case C_SEXT:
5293e12c5d1SDavid du Colombier 	case C_LEXT:
5303e12c5d1SDavid du Colombier 	case C_ESEXT:
5313e12c5d1SDavid du Colombier 	case C_ELEXT:
5323e12c5d1SDavid du Colombier 	case C_OSEXT:
5333e12c5d1SDavid du Colombier 	case C_OLEXT:
534bd389b36SDavid du Colombier 		s->used.ireg |= 1<<REGSB;
5353e12c5d1SDavid du Colombier 		if(ld)
5363e12c5d1SDavid du Colombier 			p->mark |= LOAD;
537bd389b36SDavid du Colombier 		if(ad)
538bd389b36SDavid du Colombier 			break;
539bd389b36SDavid du Colombier 		s->size = sz;
5407dd7cddfSDavid du Colombier 		s->soffset = regoff(&p->from);
541bd389b36SDavid du Colombier 
542bd389b36SDavid du Colombier 		s->used.cc |= E_MEMSB;
5433e12c5d1SDavid du Colombier 		break;
5443e12c5d1SDavid du Colombier 	}
5453e12c5d1SDavid du Colombier 
5463e12c5d1SDavid du Colombier 	c = p->reg;
5473e12c5d1SDavid du Colombier 	if(c != NREG) {
548bd389b36SDavid du Colombier 		if(p->from.type == D_FREG || p->to.type == D_FREG) {
549bd389b36SDavid du Colombier 			s->used.freg |= 1<<c;
550bd389b36SDavid du Colombier 			s->used.freg |= 1<<(c|1);
551bd389b36SDavid du Colombier 		} else
552bd389b36SDavid du Colombier 			s->used.ireg |= 1<<c;
553bd389b36SDavid du Colombier 	}
554bd389b36SDavid du Colombier 	s->set.ireg &= ~(1<<0);		/* R0 cant be set */
5553e12c5d1SDavid du Colombier }
5563e12c5d1SDavid du Colombier 
557bd389b36SDavid du Colombier /*
558bd389b36SDavid du Colombier  * test to see if 2 instrictions can be
559bd389b36SDavid du Colombier  * interchanged without changing semantics
560bd389b36SDavid du Colombier  */
5613e12c5d1SDavid du Colombier int
depend(Sch * sa,Sch * sb)562bd389b36SDavid du Colombier depend(Sch *sa, Sch *sb)
5633e12c5d1SDavid du Colombier {
564bd389b36SDavid du Colombier 	ulong x;
5653e12c5d1SDavid du Colombier 
566bd389b36SDavid du Colombier 	if(sa->set.ireg & (sb->set.ireg|sb->used.ireg))
567bd389b36SDavid du Colombier 		return 1;
568bd389b36SDavid du Colombier 	if(sb->set.ireg & sa->used.ireg)
569bd389b36SDavid du Colombier 		return 1;
5703e12c5d1SDavid du Colombier 
571bd389b36SDavid du Colombier 	if(sa->set.freg & (sb->set.freg|sb->used.freg))
5723e12c5d1SDavid du Colombier 		return 1;
573bd389b36SDavid du Colombier 	if(sb->set.freg & sa->used.freg)
5743e12c5d1SDavid du Colombier 		return 1;
575bd389b36SDavid du Colombier 
576bd389b36SDavid du Colombier 	x = (sa->set.cc & (sb->set.cc|sb->used.cc)) |
577bd389b36SDavid du Colombier 		(sb->set.cc & sa->used.cc);
578bd389b36SDavid du Colombier 	if(x) {
579bd389b36SDavid du Colombier 		/*
580bd389b36SDavid du Colombier 		 * allow SB and SP to pass each other.
581bd389b36SDavid du Colombier 		 * allow SB to pass SB iff doffsets are ok
582bd389b36SDavid du Colombier 		 * anything else conflicts
583bd389b36SDavid du Colombier 		 */
584bd389b36SDavid du Colombier 		if(x != E_MEMSP && x != E_MEMSB)
585bd389b36SDavid du Colombier 			return 1;
586bd389b36SDavid du Colombier 		x = sa->set.cc | sb->set.cc |
587bd389b36SDavid du Colombier 			sa->used.cc | sb->used.cc;
588bd389b36SDavid du Colombier 		if(x & E_MEM)
589bd389b36SDavid du Colombier 			return 1;
590bd389b36SDavid du Colombier 		if(offoverlap(sa, sb))
5913e12c5d1SDavid du Colombier 			return 1;
5923e12c5d1SDavid du Colombier 	}
5933e12c5d1SDavid du Colombier 
5943e12c5d1SDavid du Colombier 	return 0;
5953e12c5d1SDavid du Colombier }
5963e12c5d1SDavid du Colombier 
5973e12c5d1SDavid du Colombier int
offoverlap(Sch * sa,Sch * sb)598bd389b36SDavid du Colombier offoverlap(Sch *sa, Sch *sb)
5993e12c5d1SDavid du Colombier {
6003e12c5d1SDavid du Colombier 
6017dd7cddfSDavid du Colombier 	if(sa->soffset < sb->soffset) {
6027dd7cddfSDavid du Colombier 		if(sa->soffset+sa->size > sb->soffset)
6033e12c5d1SDavid du Colombier 			return 1;
604bd389b36SDavid du Colombier 		return 0;
6053e12c5d1SDavid du Colombier 	}
6067dd7cddfSDavid du Colombier 	if(sb->soffset+sb->size > sa->soffset)
607bd389b36SDavid du Colombier 		return 1;
608bd389b36SDavid du Colombier 	return 0;
609bd389b36SDavid du Colombier }
610bd389b36SDavid du Colombier 
611bd389b36SDavid du Colombier /*
612bd389b36SDavid du Colombier  * test 2 adjacent instructions
613bd389b36SDavid du Colombier  * and find out if inserted instructions
614bd389b36SDavid du Colombier  * are desired to prevent stalls.
615bd389b36SDavid du Colombier  * first instruction is a load instruction.
616bd389b36SDavid du Colombier  */
617bd389b36SDavid du Colombier int
conflict(Sch * sa,Sch * sb)618bd389b36SDavid du Colombier conflict(Sch *sa, Sch *sb)
619bd389b36SDavid du Colombier {
620bd389b36SDavid du Colombier 
621bd389b36SDavid du Colombier 	if(sa->set.ireg & sb->used.ireg)
622bd389b36SDavid du Colombier 		return 1;
623bd389b36SDavid du Colombier 	if(sa->set.freg & sb->used.freg)
624bd389b36SDavid du Colombier 		return 1;
6253e12c5d1SDavid du Colombier 	return 0;
6263e12c5d1SDavid du Colombier }
6273e12c5d1SDavid du Colombier 
6283e12c5d1SDavid du Colombier int
compound(Prog * p)6293e12c5d1SDavid du Colombier compound(Prog *p)
6303e12c5d1SDavid du Colombier {
6313e12c5d1SDavid du Colombier 	Optab *o;
6323e12c5d1SDavid du Colombier 
6333e12c5d1SDavid du Colombier 	o = oplook(p);
6343e12c5d1SDavid du Colombier 	if(o->size != 4)
6353e12c5d1SDavid du Colombier 		return 1;
6363e12c5d1SDavid du Colombier 	if(p->to.type == D_REG && p->to.reg == REGSB)
6373e12c5d1SDavid du Colombier 		return 1;
6383e12c5d1SDavid du Colombier 	return 0;
6393e12c5d1SDavid du Colombier }
640bd389b36SDavid du Colombier 
641bd389b36SDavid du Colombier void
dumpbits(Sch * s,Dep * d)642bd389b36SDavid du Colombier dumpbits(Sch *s, Dep *d)
643bd389b36SDavid du Colombier {
644bd389b36SDavid du Colombier 	int i;
645bd389b36SDavid du Colombier 
646bd389b36SDavid du Colombier 	for(i=0; i<32; i++)
647bd389b36SDavid du Colombier 		if(d->ireg & (1<<i))
648bd389b36SDavid du Colombier 			Bprint(&bso, " R%d", i);
649bd389b36SDavid du Colombier 	for(i=0; i<32; i++)
650bd389b36SDavid du Colombier 		if(d->freg & (1<<i))
651bd389b36SDavid du Colombier 			Bprint(&bso, " F%d", i);
652bd389b36SDavid du Colombier 	for(i=0; i<32; i++)
653bd389b36SDavid du Colombier 		switch(d->cc & (1<<i)) {
654bd389b36SDavid du Colombier 		default:
655bd389b36SDavid du Colombier 			break;
656bd389b36SDavid du Colombier 		case E_ICC:
657bd389b36SDavid du Colombier 			Bprint(&bso, " ICC");
658bd389b36SDavid du Colombier 			break;
659bd389b36SDavid du Colombier 		case E_FCC:
660bd389b36SDavid du Colombier 			Bprint(&bso, " FCC");
661bd389b36SDavid du Colombier 			break;
662bd389b36SDavid du Colombier 		case E_MEM:
663bd389b36SDavid du Colombier 			Bprint(&bso, " MEM%d", s->size);
664bd389b36SDavid du Colombier 			break;
665bd389b36SDavid du Colombier 		case E_MEMSB:
666bd389b36SDavid du Colombier 			Bprint(&bso, " SB%d", s->size);
667bd389b36SDavid du Colombier 			break;
668bd389b36SDavid du Colombier 		case E_MEMSP:
669bd389b36SDavid du Colombier 			Bprint(&bso, " SP%d", s->size);
670bd389b36SDavid du Colombier 			break;
671bd389b36SDavid du Colombier 		}
672bd389b36SDavid du Colombier }
673