xref: /plan9/sys/src/cmd/vl/span.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
43e12c5d1SDavid du Colombier span(void)
53e12c5d1SDavid du Colombier {
6*219b2ee8SDavid du Colombier 	Prog *p, *q;
73e12c5d1SDavid du Colombier 	Sym *setext;
83e12c5d1SDavid du Colombier 	Optab *o;
93e12c5d1SDavid du Colombier 	int m;
103e12c5d1SDavid du Colombier 	long c;
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier 	if(debug['v'])
133e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f span\n", cputime());
143e12c5d1SDavid du Colombier 	Bflush(&bso);
153e12c5d1SDavid du Colombier 	c = INITTEXT;
163e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
17*219b2ee8SDavid du Colombier 		/* bug in early 4000 chips delayslot on page boundary */
18*219b2ee8SDavid du Colombier 		if((c&(0x1000-1)) == 0xffc) {
19*219b2ee8SDavid du Colombier 			switch(p->as) {
20*219b2ee8SDavid du Colombier 			case ABGEZAL:
21*219b2ee8SDavid du Colombier 			case ABLTZAL:
22*219b2ee8SDavid du Colombier 			case AJAL:
23*219b2ee8SDavid du Colombier 			case ABEQ:
24*219b2ee8SDavid du Colombier 			case ABGEZ:
25*219b2ee8SDavid du Colombier 			case ABGTZ:
26*219b2ee8SDavid du Colombier 			case ABLEZ:
27*219b2ee8SDavid du Colombier 			case ABLTZ:
28*219b2ee8SDavid du Colombier 			case ABNE:
29*219b2ee8SDavid du Colombier 			case ABFPT:
30*219b2ee8SDavid du Colombier 			case ABFPF:
31*219b2ee8SDavid du Colombier 			case AJMP:
32*219b2ee8SDavid du Colombier 				q = prg();
33*219b2ee8SDavid du Colombier 				*q = *p;
34*219b2ee8SDavid du Colombier 				p->link = q;
35*219b2ee8SDavid du Colombier 				p->as = ANOR;
36*219b2ee8SDavid du Colombier 				p->optab = 0;
37*219b2ee8SDavid du Colombier 				p->from = zprg.from;
38*219b2ee8SDavid du Colombier 				p->from.type = D_REG;
39*219b2ee8SDavid du Colombier 				p->from.reg = REGZERO;
40*219b2ee8SDavid du Colombier 				p->to = p->from;
41*219b2ee8SDavid du Colombier 			}
42*219b2ee8SDavid du Colombier 		}
433e12c5d1SDavid du Colombier 		p->pc = c;
443e12c5d1SDavid du Colombier 		o = oplook(p);
453e12c5d1SDavid du Colombier 		m = o->size;
463e12c5d1SDavid du Colombier 		if(m == 0) {
473e12c5d1SDavid du Colombier 			if(p->as == ATEXT) {
483e12c5d1SDavid du Colombier 				curtext = p;
493e12c5d1SDavid du Colombier 				autosize = p->to.offset + 4;
503e12c5d1SDavid du Colombier 				if(p->from.sym != S)
513e12c5d1SDavid du Colombier 					p->from.sym->value = c;
523e12c5d1SDavid du Colombier 				continue;
533e12c5d1SDavid du Colombier 			}
543e12c5d1SDavid du Colombier 			diag("zero-width instruction\n%P\n", p);
553e12c5d1SDavid du Colombier 			continue;
563e12c5d1SDavid du Colombier 		}
573e12c5d1SDavid du Colombier 		c += m;
583e12c5d1SDavid du Colombier 	}
593e12c5d1SDavid du Colombier 	c = rnd(c, 8);
603e12c5d1SDavid du Colombier 
613e12c5d1SDavid du Colombier 	setext = lookup("etext", 0);
623e12c5d1SDavid du Colombier 	if(setext != S) {
633e12c5d1SDavid du Colombier 		setext->value = c;
643e12c5d1SDavid du Colombier 		textsize = c - INITTEXT;
653e12c5d1SDavid du Colombier 	}
663e12c5d1SDavid du Colombier 	if(INITRND)
673e12c5d1SDavid du Colombier 		INITDAT = rnd(c, INITRND);
683e12c5d1SDavid du Colombier 	if(debug['v'])
693e12c5d1SDavid du Colombier 		Bprint(&bso, "tsize = %lux\n", textsize);
703e12c5d1SDavid du Colombier 	Bflush(&bso);
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier void
743e12c5d1SDavid du Colombier xdefine(char *p, int t, long v)
753e12c5d1SDavid du Colombier {
763e12c5d1SDavid du Colombier 	Sym *s;
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier 	s = lookup(p, 0);
793e12c5d1SDavid du Colombier 	if(s->type == 0 || s->type == SXREF) {
803e12c5d1SDavid du Colombier 		s->type = t;
813e12c5d1SDavid du Colombier 		s->value = v;
823e12c5d1SDavid du Colombier 	}
833e12c5d1SDavid du Colombier }
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier long
863e12c5d1SDavid du Colombier regoff(Adr *a)
873e12c5d1SDavid du Colombier {
883e12c5d1SDavid du Colombier 
893e12c5d1SDavid du Colombier 	offset = 0;
903e12c5d1SDavid du Colombier 	aclass(a);
913e12c5d1SDavid du Colombier 	return offset;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier 
943e12c5d1SDavid du Colombier aclass(Adr *a)
953e12c5d1SDavid du Colombier {
963e12c5d1SDavid du Colombier 	Sym *s;
973e12c5d1SDavid du Colombier 	int t;
983e12c5d1SDavid du Colombier 
993e12c5d1SDavid du Colombier 	switch(a->type) {
1003e12c5d1SDavid du Colombier 	case D_NONE:
1013e12c5d1SDavid du Colombier 		return C_NONE;
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier 	case D_REG:
1043e12c5d1SDavid du Colombier 		return C_REG;
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	case D_FREG:
1073e12c5d1SDavid du Colombier 		return C_FREG;
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier 	case D_FCREG:
1103e12c5d1SDavid du Colombier 		return C_FCREG;
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier 	case D_MREG:
1133e12c5d1SDavid du Colombier 		return C_MREG;
1143e12c5d1SDavid du Colombier 
1153e12c5d1SDavid du Colombier 	case D_OREG:
1163e12c5d1SDavid du Colombier 		switch(a->name) {
1173e12c5d1SDavid du Colombier 		case D_EXTERN:
1183e12c5d1SDavid du Colombier 		case D_STATIC:
119*219b2ee8SDavid du Colombier 			if(a->sym == 0 || a->sym->name == 0) {
1203e12c5d1SDavid du Colombier 				print("null sym external\n");
1213e12c5d1SDavid du Colombier 				print("%D\n", a);
1223e12c5d1SDavid du Colombier 				return C_GOK;
1233e12c5d1SDavid du Colombier 			}
1243e12c5d1SDavid du Colombier 			t = a->sym->type;
1253e12c5d1SDavid du Colombier 			if(t == 0 || t == SXREF) {
1263e12c5d1SDavid du Colombier 				diag("undefined external: %s in %s\n",
1273e12c5d1SDavid du Colombier 					a->sym->name, TNAME);
1283e12c5d1SDavid du Colombier 				a->sym->type = SDATA;
1293e12c5d1SDavid du Colombier 			}
1303e12c5d1SDavid du Colombier 			offset = a->sym->value + a->offset - BIG;
1313e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG)
1323e12c5d1SDavid du Colombier 				return C_SEXT;
1333e12c5d1SDavid du Colombier 			return C_LEXT;
1343e12c5d1SDavid du Colombier 		case D_AUTO:
1353e12c5d1SDavid du Colombier 			offset = autosize + a->offset;
1363e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG)
1373e12c5d1SDavid du Colombier 				return C_SAUTO;
1383e12c5d1SDavid du Colombier 			return C_LAUTO;
1393e12c5d1SDavid du Colombier 
1403e12c5d1SDavid du Colombier 		case D_PARAM:
1413e12c5d1SDavid du Colombier 			offset = autosize + a->offset + 4L;
1423e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG)
1433e12c5d1SDavid du Colombier 				return C_SAUTO;
1443e12c5d1SDavid du Colombier 			return C_LAUTO;
1453e12c5d1SDavid du Colombier 		case D_NONE:
1463e12c5d1SDavid du Colombier 			offset = a->offset;
1473e12c5d1SDavid du Colombier 			if(offset == 0)
1483e12c5d1SDavid du Colombier 				return C_ZOREG;
1493e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG)
1503e12c5d1SDavid du Colombier 				return C_SOREG;
1513e12c5d1SDavid du Colombier 			return C_LOREG;
1523e12c5d1SDavid du Colombier 		}
1533e12c5d1SDavid du Colombier 		return C_GOK;
1543e12c5d1SDavid du Colombier 
1553e12c5d1SDavid du Colombier 	case D_HI:
1563e12c5d1SDavid du Colombier 		return C_LO;
1573e12c5d1SDavid du Colombier 	case D_LO:
1583e12c5d1SDavid du Colombier 		return C_HI;
1593e12c5d1SDavid du Colombier 
160*219b2ee8SDavid du Colombier 	case D_OCONST:
161*219b2ee8SDavid du Colombier 		switch(a->name) {
162*219b2ee8SDavid du Colombier 		case D_EXTERN:
163*219b2ee8SDavid du Colombier 		case D_STATIC:
164*219b2ee8SDavid du Colombier 			s = a->sym;
165*219b2ee8SDavid du Colombier 			t = s->type;
166*219b2ee8SDavid du Colombier 			if(t == 0 || t == SXREF) {
167*219b2ee8SDavid du Colombier 				diag("undefined external: %s in %s\n",
168*219b2ee8SDavid du Colombier 					s->name, TNAME);
169*219b2ee8SDavid du Colombier 				s->type = SDATA;
170*219b2ee8SDavid du Colombier 			}
171*219b2ee8SDavid du Colombier 			offset = s->value + a->offset + INITDAT;
172*219b2ee8SDavid du Colombier 			if(s->type == STEXT || s->type == SLEAF)
173*219b2ee8SDavid du Colombier 				offset = s->value + a->offset;
174*219b2ee8SDavid du Colombier 			return C_LCON;
175*219b2ee8SDavid du Colombier 		}
176*219b2ee8SDavid du Colombier 		return C_GOK;
177*219b2ee8SDavid du Colombier 
1783e12c5d1SDavid du Colombier 	case D_CONST:
1793e12c5d1SDavid du Colombier 		switch(a->name) {
1803e12c5d1SDavid du Colombier 
1813e12c5d1SDavid du Colombier 		case D_NONE:
1823e12c5d1SDavid du Colombier 			offset = a->offset;
183*219b2ee8SDavid du Colombier 		consize:
1843e12c5d1SDavid du Colombier 			if(offset > 0) {
1853e12c5d1SDavid du Colombier 				if(offset <= 0x7fff)
1863e12c5d1SDavid du Colombier 					return C_SCON;
1873e12c5d1SDavid du Colombier 				if(offset <= 0xffff)
1883e12c5d1SDavid du Colombier 					return C_ANDCON;
1893e12c5d1SDavid du Colombier 				if((offset & 0xffff) == 0)
1903e12c5d1SDavid du Colombier 					return C_UCON;
1913e12c5d1SDavid du Colombier 				return C_LCON;
1923e12c5d1SDavid du Colombier 			}
1933e12c5d1SDavid du Colombier 			if(offset == 0)
1943e12c5d1SDavid du Colombier 				return C_ZCON;
1953e12c5d1SDavid du Colombier 			if(offset >= -0x8000)
1963e12c5d1SDavid du Colombier 				return C_ADDCON;
1973e12c5d1SDavid du Colombier 			if((offset & 0xffff) == 0)
1983e12c5d1SDavid du Colombier 				return C_UCON;
1993e12c5d1SDavid du Colombier 			return C_LCON;
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier 		case D_EXTERN:
2023e12c5d1SDavid du Colombier 		case D_STATIC:
2033e12c5d1SDavid du Colombier 			s = a->sym;
204*219b2ee8SDavid du Colombier 			if(s == S)
205*219b2ee8SDavid du Colombier 				break;
2063e12c5d1SDavid du Colombier 			t = s->type;
207*219b2ee8SDavid du Colombier 			switch(t) {
208*219b2ee8SDavid du Colombier 			case 0:
209*219b2ee8SDavid du Colombier 			case SXREF:
2103e12c5d1SDavid du Colombier 				diag("undefined external: %s in %s\n",
2113e12c5d1SDavid du Colombier 					s->name, TNAME);
2123e12c5d1SDavid du Colombier 				s->type = SDATA;
213*219b2ee8SDavid du Colombier 				break;
214*219b2ee8SDavid du Colombier 			case SCONST:
215*219b2ee8SDavid du Colombier 				offset = s->value + a->offset;
216*219b2ee8SDavid du Colombier 				goto consize;
217*219b2ee8SDavid du Colombier 			case STEXT:
218*219b2ee8SDavid du Colombier 			case SLEAF:
2193e12c5d1SDavid du Colombier 				offset = s->value + a->offset;
2203e12c5d1SDavid du Colombier 				return C_LCON;
2213e12c5d1SDavid du Colombier 			}
2223e12c5d1SDavid du Colombier 			offset = s->value + a->offset - BIG;
2233e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG && offset != 0L)
2243e12c5d1SDavid du Colombier 				return C_SECON;
2253e12c5d1SDavid du Colombier 			offset = s->value + a->offset + INITDAT;
2263e12c5d1SDavid du Colombier 			return C_LCON;
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 		case D_AUTO:
2293e12c5d1SDavid du Colombier 			offset = autosize + a->offset;
2303e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG)
2313e12c5d1SDavid du Colombier 				return C_SACON;
2323e12c5d1SDavid du Colombier 			return C_LACON;
2333e12c5d1SDavid du Colombier 
2343e12c5d1SDavid du Colombier 		case D_PARAM:
2353e12c5d1SDavid du Colombier 			offset = autosize + a->offset + 4L;
2363e12c5d1SDavid du Colombier 			if(offset >= -BIG && offset < BIG)
2373e12c5d1SDavid du Colombier 				return C_SACON;
2383e12c5d1SDavid du Colombier 			return C_LACON;
2393e12c5d1SDavid du Colombier 		}
2403e12c5d1SDavid du Colombier 		return C_GOK;
2413e12c5d1SDavid du Colombier 
2423e12c5d1SDavid du Colombier 	case D_BRANCH:
2433e12c5d1SDavid du Colombier 		return C_SBRA;
2443e12c5d1SDavid du Colombier 	}
2453e12c5d1SDavid du Colombier 	return C_GOK;
2463e12c5d1SDavid du Colombier }
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier Optab*
2493e12c5d1SDavid du Colombier oplook(Prog *p)
2503e12c5d1SDavid du Colombier {
2513e12c5d1SDavid du Colombier 	int a1, a2, a3, r;
2523e12c5d1SDavid du Colombier 	char *c1, *c3;
2533e12c5d1SDavid du Colombier 	Optab *o, *e;
2543e12c5d1SDavid du Colombier 
2553e12c5d1SDavid du Colombier 	a1 = p->optab;
2563e12c5d1SDavid du Colombier 	if(a1)
2573e12c5d1SDavid du Colombier 		return optab+(a1-1);
2583e12c5d1SDavid du Colombier 	a1 = p->from.class;
2593e12c5d1SDavid du Colombier 	if(a1 == 0) {
2603e12c5d1SDavid du Colombier 		a1 = aclass(&p->from) + 1;
2613e12c5d1SDavid du Colombier 		p->from.class = a1;
2623e12c5d1SDavid du Colombier 	}
2633e12c5d1SDavid du Colombier 	a1--;
2643e12c5d1SDavid du Colombier 	a3 = p->to.class;
2653e12c5d1SDavid du Colombier 	if(a3 == 0) {
2663e12c5d1SDavid du Colombier 		a3 = aclass(&p->to) + 1;
2673e12c5d1SDavid du Colombier 		p->to.class = a3;
2683e12c5d1SDavid du Colombier 	}
2693e12c5d1SDavid du Colombier 	a3--;
2703e12c5d1SDavid du Colombier 	a2 = C_NONE;
2713e12c5d1SDavid du Colombier 	if(p->reg != NREG)
2723e12c5d1SDavid du Colombier 		a2 = C_REG;
2733e12c5d1SDavid du Colombier 	r = p->as;
2743e12c5d1SDavid du Colombier 	o = oprange[r].start;
2753e12c5d1SDavid du Colombier 	if(o == 0) {
2763e12c5d1SDavid du Colombier 		a1 = opcross[repop[r]][a1][a2][a3];
2773e12c5d1SDavid du Colombier 		if(a1) {
2783e12c5d1SDavid du Colombier 			p->optab = a1+1;
2793e12c5d1SDavid du Colombier 			return optab+a1;
2803e12c5d1SDavid du Colombier 		}
2813e12c5d1SDavid du Colombier 		o = oprange[r].stop; /* just generate an error */
2823e12c5d1SDavid du Colombier 	}
2833e12c5d1SDavid du Colombier 	e = oprange[r].stop;
2843e12c5d1SDavid du Colombier 	c1 = xcmp[a1];
2853e12c5d1SDavid du Colombier 	c3 = xcmp[a3];
2863e12c5d1SDavid du Colombier 	for(; o<e; o++)
2873e12c5d1SDavid du Colombier 		if(o->a2 == a2)
2883e12c5d1SDavid du Colombier 		if(c1[o->a1])
2893e12c5d1SDavid du Colombier 		if(c3[o->a3]) {
2903e12c5d1SDavid du Colombier 			p->optab = (o-optab)+1;
2913e12c5d1SDavid du Colombier 			return o;
2923e12c5d1SDavid du Colombier 		}
2933e12c5d1SDavid du Colombier 	diag("illegal combination %A %d %d %d\n",
2943e12c5d1SDavid du Colombier 		p->as, a1, a2, a3);
2953e12c5d1SDavid du Colombier 	if(!debug['a'])
2963e12c5d1SDavid du Colombier 		prasm(p);
2973e12c5d1SDavid du Colombier 	return o;
2983e12c5d1SDavid du Colombier }
2993e12c5d1SDavid du Colombier 
3003e12c5d1SDavid du Colombier int
3013e12c5d1SDavid du Colombier cmp(int a, int b)
3023e12c5d1SDavid du Colombier {
3033e12c5d1SDavid du Colombier 
3043e12c5d1SDavid du Colombier 	if(a == b)
3053e12c5d1SDavid du Colombier 		return 1;
3063e12c5d1SDavid du Colombier 	switch(a) {
3073e12c5d1SDavid du Colombier 	case C_LCON:
3083e12c5d1SDavid du Colombier 		if(b == C_ZCON || b == C_SCON || b == C_UCON ||
3093e12c5d1SDavid du Colombier 		   b == C_ADDCON || b == C_ANDCON)
3103e12c5d1SDavid du Colombier 			return 1;
3113e12c5d1SDavid du Colombier 		break;
3123e12c5d1SDavid du Colombier 	case C_ADD0CON:
3133e12c5d1SDavid du Colombier 		if(b == C_ADDCON)
3143e12c5d1SDavid du Colombier 			return 1;
3153e12c5d1SDavid du Colombier 	case C_ADDCON:
3163e12c5d1SDavid du Colombier 		if(b == C_ZCON || b == C_SCON)
3173e12c5d1SDavid du Colombier 			return 1;
3183e12c5d1SDavid du Colombier 		break;
3193e12c5d1SDavid du Colombier 	case C_AND0CON:
3203e12c5d1SDavid du Colombier 		if(b == C_ANDCON)
3213e12c5d1SDavid du Colombier 			return 1;
3223e12c5d1SDavid du Colombier 	case C_ANDCON:
3233e12c5d1SDavid du Colombier 		if(b == C_ZCON || b == C_SCON)
3243e12c5d1SDavid du Colombier 			return 1;
3253e12c5d1SDavid du Colombier 		break;
3263e12c5d1SDavid du Colombier 	case C_UCON:
3273e12c5d1SDavid du Colombier 		if(b == C_ZCON)
3283e12c5d1SDavid du Colombier 			return 1;
3293e12c5d1SDavid du Colombier 		break;
3303e12c5d1SDavid du Colombier 	case C_SCON:
3313e12c5d1SDavid du Colombier 		if(b == C_ZCON)
3323e12c5d1SDavid du Colombier 			return 1;
3333e12c5d1SDavid du Colombier 		break;
3343e12c5d1SDavid du Colombier 	case C_LACON:
3353e12c5d1SDavid du Colombier 		if(b == C_SACON)
3363e12c5d1SDavid du Colombier 			return 1;
3373e12c5d1SDavid du Colombier 		break;
3383e12c5d1SDavid du Colombier 	case C_LBRA:
3393e12c5d1SDavid du Colombier 		if(b == C_SBRA)
3403e12c5d1SDavid du Colombier 			return 1;
3413e12c5d1SDavid du Colombier 		break;
3423e12c5d1SDavid du Colombier 	case C_LEXT:
3433e12c5d1SDavid du Colombier 		if(b == C_SEXT)
3443e12c5d1SDavid du Colombier 			return 1;
3453e12c5d1SDavid du Colombier 		break;
3463e12c5d1SDavid du Colombier 	case C_LAUTO:
3473e12c5d1SDavid du Colombier 		if(b == C_SAUTO)
3483e12c5d1SDavid du Colombier 			return 1;
3493e12c5d1SDavid du Colombier 		break;
3503e12c5d1SDavid du Colombier 	case C_REG:
3513e12c5d1SDavid du Colombier 		if(b == C_ZCON)
3523e12c5d1SDavid du Colombier 			return 1;
3533e12c5d1SDavid du Colombier 		break;
3543e12c5d1SDavid du Colombier 	case C_LOREG:
3553e12c5d1SDavid du Colombier 		if(b == C_ZOREG || b == C_SOREG)
3563e12c5d1SDavid du Colombier 			return 1;
3573e12c5d1SDavid du Colombier 		break;
3583e12c5d1SDavid du Colombier 	case C_SOREG:
3593e12c5d1SDavid du Colombier 		if(b == C_ZOREG)
3603e12c5d1SDavid du Colombier 			return 1;
3613e12c5d1SDavid du Colombier 		break;
3623e12c5d1SDavid du Colombier 	}
3633e12c5d1SDavid du Colombier 	return 0;
3643e12c5d1SDavid du Colombier }
3653e12c5d1SDavid du Colombier 
3663e12c5d1SDavid du Colombier int
3673e12c5d1SDavid du Colombier ocmp(void *a1, void *a2)
3683e12c5d1SDavid du Colombier {
3693e12c5d1SDavid du Colombier 	Optab *p1, *p2;
3703e12c5d1SDavid du Colombier 	int n;
3713e12c5d1SDavid du Colombier 
3723e12c5d1SDavid du Colombier 	p1 = a1;
3733e12c5d1SDavid du Colombier 	p2 = a2;
3743e12c5d1SDavid du Colombier 	n = p1->as - p2->as;
3753e12c5d1SDavid du Colombier 	if(n)
3763e12c5d1SDavid du Colombier 		return n;
3773e12c5d1SDavid du Colombier 	n = p1->a1 - p2->a1;
3783e12c5d1SDavid du Colombier 	if(n)
3793e12c5d1SDavid du Colombier 		return n;
3803e12c5d1SDavid du Colombier 	n = p1->a2 - p2->a2;
3813e12c5d1SDavid du Colombier 	if(n)
3823e12c5d1SDavid du Colombier 		return n;
3833e12c5d1SDavid du Colombier 	n = p1->a3 - p2->a3;
3843e12c5d1SDavid du Colombier 	if(n)
3853e12c5d1SDavid du Colombier 		return n;
3863e12c5d1SDavid du Colombier 	return 0;
3873e12c5d1SDavid du Colombier }
3883e12c5d1SDavid du Colombier 
3893e12c5d1SDavid du Colombier void
3903e12c5d1SDavid du Colombier buildop(void)
3913e12c5d1SDavid du Colombier {
3923e12c5d1SDavid du Colombier 	int i, n, r;
3933e12c5d1SDavid du Colombier 
3943e12c5d1SDavid du Colombier 	for(i=0; i<32; i++)
3953e12c5d1SDavid du Colombier 		for(n=0; n<32; n++)
3963e12c5d1SDavid du Colombier 			xcmp[i][n] = cmp(n, i);
3973e12c5d1SDavid du Colombier 	for(n=0; optab[n].as != AXXX; n++)
3983e12c5d1SDavid du Colombier 		;
3993e12c5d1SDavid du Colombier 	qsort(optab, n, sizeof(optab[0]), ocmp);
4003e12c5d1SDavid du Colombier 	for(i=0; i<n; i++) {
4013e12c5d1SDavid du Colombier 		r = optab[i].as;
4023e12c5d1SDavid du Colombier 		oprange[r].start = optab+i;
4033e12c5d1SDavid du Colombier 		while(optab[i].as == r)
4043e12c5d1SDavid du Colombier 			i++;
4053e12c5d1SDavid du Colombier 		oprange[r].stop = optab+i;
4063e12c5d1SDavid du Colombier 		i--;
4073e12c5d1SDavid du Colombier 
4083e12c5d1SDavid du Colombier 		switch(r)
4093e12c5d1SDavid du Colombier 		{
4103e12c5d1SDavid du Colombier 		default:
4113e12c5d1SDavid du Colombier 			diag("unknown op in build: %A\n", r);
4123e12c5d1SDavid du Colombier 			errorexit();
4133e12c5d1SDavid du Colombier 		case AABSF:
4143e12c5d1SDavid du Colombier 			oprange[AMOVFD] = oprange[r];
4153e12c5d1SDavid du Colombier 			oprange[AMOVDF] = oprange[r];
4163e12c5d1SDavid du Colombier 			oprange[AMOVWF] = oprange[r];
4173e12c5d1SDavid du Colombier 			oprange[AMOVFW] = oprange[r];
4183e12c5d1SDavid du Colombier 			oprange[AMOVWD] = oprange[r];
4193e12c5d1SDavid du Colombier 			oprange[AMOVDW] = oprange[r];
4203e12c5d1SDavid du Colombier 			oprange[ANEGF] = oprange[r];
4213e12c5d1SDavid du Colombier 			oprange[ANEGD] = oprange[r];
4223e12c5d1SDavid du Colombier 			oprange[AABSD] = oprange[r];
4233e12c5d1SDavid du Colombier 			break;
4243e12c5d1SDavid du Colombier 		case AADD:
4253e12c5d1SDavid du Colombier 			buildrep(1, AADD);
4263e12c5d1SDavid du Colombier 			oprange[ASGT] = oprange[r];
4273e12c5d1SDavid du Colombier 			repop[ASGT] = 1;
4283e12c5d1SDavid du Colombier 			oprange[ASGTU] = oprange[r];
4293e12c5d1SDavid du Colombier 			repop[ASGTU] = 1;
4303e12c5d1SDavid du Colombier 			oprange[AADDU] = oprange[r];
4313e12c5d1SDavid du Colombier 			repop[AADDU] = 1;
4323e12c5d1SDavid du Colombier 			break;
4333e12c5d1SDavid du Colombier 		case AADDF:
4343e12c5d1SDavid du Colombier 			oprange[ADIVF] = oprange[r];
4353e12c5d1SDavid du Colombier 			oprange[ADIVD] = oprange[r];
4363e12c5d1SDavid du Colombier 			oprange[AMULF] = oprange[r];
4373e12c5d1SDavid du Colombier 			oprange[AMULD] = oprange[r];
4383e12c5d1SDavid du Colombier 			oprange[ASUBF] = oprange[r];
4393e12c5d1SDavid du Colombier 			oprange[ASUBD] = oprange[r];
4403e12c5d1SDavid du Colombier 			oprange[AADDD] = oprange[r];
4413e12c5d1SDavid du Colombier 			break;
4423e12c5d1SDavid du Colombier 		case AAND:
4433e12c5d1SDavid du Colombier 			buildrep(2, AAND);
4443e12c5d1SDavid du Colombier 			oprange[AXOR] = oprange[r];
4453e12c5d1SDavid du Colombier 			repop[AXOR] = 2;
4463e12c5d1SDavid du Colombier 			oprange[AOR] = oprange[r];
4473e12c5d1SDavid du Colombier 			repop[AOR] = 2;
4483e12c5d1SDavid du Colombier 			break;
4493e12c5d1SDavid du Colombier 		case ABEQ:
4503e12c5d1SDavid du Colombier 			oprange[ABNE] = oprange[r];
4513e12c5d1SDavid du Colombier 			break;
4523e12c5d1SDavid du Colombier 		case ABLEZ:
4533e12c5d1SDavid du Colombier 			oprange[ABGEZ] = oprange[r];
4543e12c5d1SDavid du Colombier 			oprange[ABGEZAL] = oprange[r];
4553e12c5d1SDavid du Colombier 			oprange[ABLTZ] = oprange[r];
4563e12c5d1SDavid du Colombier 			oprange[ABLTZAL] = oprange[r];
4573e12c5d1SDavid du Colombier 			oprange[ABGTZ] = oprange[r];
4583e12c5d1SDavid du Colombier 			break;
4593e12c5d1SDavid du Colombier 		case AMOVB:
4603e12c5d1SDavid du Colombier 			buildrep(3, AMOVB);
4613e12c5d1SDavid du Colombier 			oprange[AMOVH] = oprange[r];
4623e12c5d1SDavid du Colombier 			repop[AMOVH] = 3;
4633e12c5d1SDavid du Colombier 			break;
4643e12c5d1SDavid du Colombier 		case AMOVBU:
4653e12c5d1SDavid du Colombier 			buildrep(4, AMOVBU);
4663e12c5d1SDavid du Colombier 			oprange[AMOVHU] = oprange[r];
4673e12c5d1SDavid du Colombier 			repop[AMOVHU] = 4;
4683e12c5d1SDavid du Colombier 			break;
4693e12c5d1SDavid du Colombier 		case AMUL:
4703e12c5d1SDavid du Colombier 			oprange[AREM] = oprange[r];
4713e12c5d1SDavid du Colombier 			oprange[AREMU] = oprange[r];
4723e12c5d1SDavid du Colombier 			oprange[ADIVU] = oprange[r];
4733e12c5d1SDavid du Colombier 			oprange[AMULU] = oprange[r];
4743e12c5d1SDavid du Colombier 			oprange[ADIV] = oprange[r];
4753e12c5d1SDavid du Colombier 			break;
4763e12c5d1SDavid du Colombier 		case ASLL:
4773e12c5d1SDavid du Colombier 			oprange[ASRL] = oprange[r];
4783e12c5d1SDavid du Colombier 			oprange[ASRA] = oprange[r];
479*219b2ee8SDavid du Colombier 			oprange[ASLLV] = oprange[r];
480*219b2ee8SDavid du Colombier 			oprange[ASRAV] = oprange[r];
481*219b2ee8SDavid du Colombier 			oprange[ASRLV] = oprange[r];
4823e12c5d1SDavid du Colombier 			break;
4833e12c5d1SDavid du Colombier 		case ASUB:
4843e12c5d1SDavid du Colombier 			oprange[ASUBU] = oprange[r];
4853e12c5d1SDavid du Colombier 			oprange[ANOR] = oprange[r];
4863e12c5d1SDavid du Colombier 			break;
4873e12c5d1SDavid du Colombier 		case ASYSCALL:
4883e12c5d1SDavid du Colombier 			oprange[ATLBP] = oprange[r];
4893e12c5d1SDavid du Colombier 			oprange[ATLBR] = oprange[r];
4903e12c5d1SDavid du Colombier 			oprange[ATLBWI] = oprange[r];
4913e12c5d1SDavid du Colombier 			oprange[ATLBWR] = oprange[r];
4923e12c5d1SDavid du Colombier 			break;
4933e12c5d1SDavid du Colombier 		case ACMPEQF:
4943e12c5d1SDavid du Colombier 			oprange[ACMPGTF] = oprange[r];
4953e12c5d1SDavid du Colombier 			oprange[ACMPGTD] = oprange[r];
4963e12c5d1SDavid du Colombier 			oprange[ACMPGEF] = oprange[r];
4973e12c5d1SDavid du Colombier 			oprange[ACMPGED] = oprange[r];
4983e12c5d1SDavid du Colombier 			oprange[ACMPEQD] = oprange[r];
4993e12c5d1SDavid du Colombier 			break;
5003e12c5d1SDavid du Colombier 		case ABFPT:
5013e12c5d1SDavid du Colombier 			oprange[ABFPF] = oprange[r];
5023e12c5d1SDavid du Colombier 			break;
5033e12c5d1SDavid du Colombier 		case AMOVWL:
5043e12c5d1SDavid du Colombier 			oprange[AMOVWR] = oprange[r];
505*219b2ee8SDavid du Colombier 			oprange[AMOVVR] = oprange[r];
506*219b2ee8SDavid du Colombier 			oprange[AMOVVL] = oprange[r];
5073e12c5d1SDavid du Colombier 			break;
5083e12c5d1SDavid du Colombier 		case AMOVW:
5093e12c5d1SDavid du Colombier 			buildrep(0, AMOVW);
5103e12c5d1SDavid du Colombier 			break;
5113e12c5d1SDavid du Colombier 		case AMOVD:
5123e12c5d1SDavid du Colombier 			buildrep(5, AMOVD);
5133e12c5d1SDavid du Colombier 			break;
5143e12c5d1SDavid du Colombier 		case AMOVF:
5153e12c5d1SDavid du Colombier 			buildrep(6, AMOVF);
5163e12c5d1SDavid du Colombier 			break;
517*219b2ee8SDavid du Colombier 		case AMOVV:
518*219b2ee8SDavid du Colombier 			buildrep(7, AMOVV);
519*219b2ee8SDavid du Colombier 			break;
520bd389b36SDavid du Colombier 		case ABREAK:
5213e12c5d1SDavid du Colombier 		case AWORD:
5223e12c5d1SDavid du Colombier 		case ARFE:
5233e12c5d1SDavid du Colombier 		case AJAL:
5243e12c5d1SDavid du Colombier 		case AJMP:
5253e12c5d1SDavid du Colombier 		case ATEXT:
5263e12c5d1SDavid du Colombier 			break;
5273e12c5d1SDavid du Colombier 		}
5283e12c5d1SDavid du Colombier 	}
5293e12c5d1SDavid du Colombier }
5303e12c5d1SDavid du Colombier 
5313e12c5d1SDavid du Colombier void
5323e12c5d1SDavid du Colombier buildrep(int x, int as)
5333e12c5d1SDavid du Colombier {
5343e12c5d1SDavid du Colombier 	Opcross *p;
5353e12c5d1SDavid du Colombier 	Optab *e, *s, *o;
5363e12c5d1SDavid du Colombier 	int a1, a2, a3, n;
5373e12c5d1SDavid du Colombier 
538*219b2ee8SDavid du Colombier 	if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
5393e12c5d1SDavid du Colombier 		diag("assumptions fail in buildrep");
5403e12c5d1SDavid du Colombier 		errorexit();
5413e12c5d1SDavid du Colombier 	}
5423e12c5d1SDavid du Colombier 	repop[as] = x;
5433e12c5d1SDavid du Colombier 	p = (opcross + x);
5443e12c5d1SDavid du Colombier 	s = oprange[as].start;
5453e12c5d1SDavid du Colombier 	e = oprange[as].stop;
5463e12c5d1SDavid du Colombier 	for(o=e-1; o>=s; o--) {
5473e12c5d1SDavid du Colombier 		n = o-optab;
5483e12c5d1SDavid du Colombier 		for(a2=0; a2<2; a2++) {
5493e12c5d1SDavid du Colombier 			if(a2) {
5503e12c5d1SDavid du Colombier 				if(o->a2 == C_NONE)
5513e12c5d1SDavid du Colombier 					continue;
5523e12c5d1SDavid du Colombier 			} else
5533e12c5d1SDavid du Colombier 				if(o->a2 != C_NONE)
5543e12c5d1SDavid du Colombier 					continue;
5553e12c5d1SDavid du Colombier 			for(a1=0; a1<32; a1++) {
5563e12c5d1SDavid du Colombier 				if(!xcmp[a1][o->a1])
5573e12c5d1SDavid du Colombier 					continue;
5583e12c5d1SDavid du Colombier 				for(a3=0; a3<32; a3++)
5593e12c5d1SDavid du Colombier 					if(xcmp[a3][o->a3])
5603e12c5d1SDavid du Colombier 						(*p)[a1][a2][a3] = n;
5613e12c5d1SDavid du Colombier 			}
5623e12c5d1SDavid du Colombier 		}
5633e12c5d1SDavid du Colombier 	}
5643e12c5d1SDavid du Colombier 	oprange[as].start = 0;
5653e12c5d1SDavid du Colombier }
566