xref: /plan9/sys/src/cmd/5l/span.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
17dd7cddfSDavid du Colombier #include	"l.h"
27dd7cddfSDavid du Colombier 
37dd7cddfSDavid du Colombier static struct {
47dd7cddfSDavid du Colombier 	ulong	start;
57dd7cddfSDavid du Colombier 	ulong	size;
67dd7cddfSDavid du Colombier } pool;
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier void	checkpool(Prog*);
97dd7cddfSDavid du Colombier void 	flushpool(Prog*, int);
107dd7cddfSDavid du Colombier 
117dd7cddfSDavid du Colombier void
127dd7cddfSDavid du Colombier span(void)
137dd7cddfSDavid du Colombier {
147dd7cddfSDavid du Colombier 	Prog *p;
15*9a747e4fSDavid du Colombier 	Sym *setext, *s;
167dd7cddfSDavid du Colombier 	Optab *o;
17*9a747e4fSDavid du Colombier 	int m, bflag, i;
18*9a747e4fSDavid du Colombier 	long c, otxt, v;
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier 	if(debug['v'])
217dd7cddfSDavid du Colombier 		Bprint(&bso, "%5.2f span\n", cputime());
227dd7cddfSDavid du Colombier 	Bflush(&bso);
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier 	bflag = 0;
257dd7cddfSDavid du Colombier 	c = INITTEXT;
267dd7cddfSDavid du Colombier 	otxt = c;
277dd7cddfSDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
287dd7cddfSDavid du Colombier 		p->pc = c;
297dd7cddfSDavid du Colombier 		o = oplook(p);
307dd7cddfSDavid du Colombier 		m = o->size;
317dd7cddfSDavid du Colombier 		if(m == 0) {
327dd7cddfSDavid du Colombier 			if(p->as == ATEXT) {
337dd7cddfSDavid du Colombier 				curtext = p;
347dd7cddfSDavid du Colombier 				autosize = p->to.offset + 4;
357dd7cddfSDavid du Colombier 				if(p->from.sym != S)
367dd7cddfSDavid du Colombier 					p->from.sym->value = c;
377dd7cddfSDavid du Colombier 				/* need passes to resolve branches */
387dd7cddfSDavid du Colombier 				if(c-otxt >= 1L<<17)
397dd7cddfSDavid du Colombier 					bflag = 1;
407dd7cddfSDavid du Colombier 				otxt = c;
417dd7cddfSDavid du Colombier 				continue;
427dd7cddfSDavid du Colombier 			}
437dd7cddfSDavid du Colombier 			diag("zero-width instruction\n%P\n", p);
447dd7cddfSDavid du Colombier 			continue;
457dd7cddfSDavid du Colombier 		}
4659cc4ca5SDavid du Colombier 		switch(o->flag & (LFROM|LTO|LPOOL)) {
477dd7cddfSDavid du Colombier 		case LFROM:
487dd7cddfSDavid du Colombier 			addpool(p, &p->from);
497dd7cddfSDavid du Colombier 			break;
507dd7cddfSDavid du Colombier 		case LTO:
517dd7cddfSDavid du Colombier 			addpool(p, &p->to);
527dd7cddfSDavid du Colombier 			break;
537dd7cddfSDavid du Colombier 		case LPOOL:
5459cc4ca5SDavid du Colombier 			if ((p->scond&C_SCOND) == 14)
557dd7cddfSDavid du Colombier 				flushpool(p, 0);
567dd7cddfSDavid du Colombier 			break;
577dd7cddfSDavid du Colombier 		}
5859cc4ca5SDavid du Colombier 		if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14)
5959cc4ca5SDavid du Colombier 			flushpool(p, 0);
607dd7cddfSDavid du Colombier 		c += m;
617dd7cddfSDavid du Colombier 		if(blitrl)
627dd7cddfSDavid du Colombier 			checkpool(p);
637dd7cddfSDavid du Colombier 	}
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier 	/*
667dd7cddfSDavid du Colombier 	 * if any procedure is large enough to
677dd7cddfSDavid du Colombier 	 * generate a large SBRA branch, then
687dd7cddfSDavid du Colombier 	 * generate extra passes putting branches
697dd7cddfSDavid du Colombier 	 * around jmps to fix. this is rare.
707dd7cddfSDavid du Colombier 	 */
717dd7cddfSDavid du Colombier 	while(bflag) {
727dd7cddfSDavid du Colombier 		if(debug['v'])
737dd7cddfSDavid du Colombier 			Bprint(&bso, "%5.2f span1\n", cputime());
747dd7cddfSDavid du Colombier 		bflag = 0;
757dd7cddfSDavid du Colombier 		c = INITTEXT;
767dd7cddfSDavid du Colombier 		for(p = firstp; p != P; p = p->link) {
777dd7cddfSDavid du Colombier 			p->pc = c;
787dd7cddfSDavid du Colombier 			o = oplook(p);
797dd7cddfSDavid du Colombier /* very larg branches
807dd7cddfSDavid du Colombier 			if(o->type == 6 && p->cond) {
817dd7cddfSDavid du Colombier 				otxt = p->cond->pc - c;
827dd7cddfSDavid du Colombier 				if(otxt < 0)
837dd7cddfSDavid du Colombier 					otxt = -otxt;
847dd7cddfSDavid du Colombier 				if(otxt >= (1L<<17) - 10) {
857dd7cddfSDavid du Colombier 					q = prg();
867dd7cddfSDavid du Colombier 					q->link = p->link;
877dd7cddfSDavid du Colombier 					p->link = q;
887dd7cddfSDavid du Colombier 					q->as = AB;
897dd7cddfSDavid du Colombier 					q->to.type = D_BRANCH;
907dd7cddfSDavid du Colombier 					q->cond = p->cond;
917dd7cddfSDavid du Colombier 					p->cond = q;
927dd7cddfSDavid du Colombier 					q = prg();
937dd7cddfSDavid du Colombier 					q->link = p->link;
947dd7cddfSDavid du Colombier 					p->link = q;
957dd7cddfSDavid du Colombier 					q->as = AB;
967dd7cddfSDavid du Colombier 					q->to.type = D_BRANCH;
977dd7cddfSDavid du Colombier 					q->cond = q->link->link;
987dd7cddfSDavid du Colombier 					bflag = 1;
997dd7cddfSDavid du Colombier 				}
1007dd7cddfSDavid du Colombier 			}
1017dd7cddfSDavid du Colombier  */
1027dd7cddfSDavid du Colombier 			m = o->size;
1037dd7cddfSDavid du Colombier 			if(m == 0) {
1047dd7cddfSDavid du Colombier 				if(p->as == ATEXT) {
1057dd7cddfSDavid du Colombier 					curtext = p;
1067dd7cddfSDavid du Colombier 					autosize = p->to.offset + 4;
1077dd7cddfSDavid du Colombier 					if(p->from.sym != S)
1087dd7cddfSDavid du Colombier 						p->from.sym->value = c;
1097dd7cddfSDavid du Colombier 					continue;
1107dd7cddfSDavid du Colombier 				}
1117dd7cddfSDavid du Colombier 				diag("zero-width instruction\n%P\n", p);
1127dd7cddfSDavid du Colombier 				continue;
1137dd7cddfSDavid du Colombier 			}
1147dd7cddfSDavid du Colombier 			c += m;
1157dd7cddfSDavid du Colombier 		}
1167dd7cddfSDavid du Colombier 	}
117*9a747e4fSDavid du Colombier 
118*9a747e4fSDavid du Colombier 	if(debug['t']) {
119*9a747e4fSDavid du Colombier 		/*
120*9a747e4fSDavid du Colombier 		 * add strings to text segment
121*9a747e4fSDavid du Colombier 		 */
122*9a747e4fSDavid du Colombier 		c = rnd(c, 8);
123*9a747e4fSDavid du Colombier 		for(i=0; i<NHASH; i++)
124*9a747e4fSDavid du Colombier 		for(s = hash[i]; s != S; s = s->link) {
125*9a747e4fSDavid du Colombier 			if(s->type != SSTRING)
126*9a747e4fSDavid du Colombier 				continue;
127*9a747e4fSDavid du Colombier 			v = s->value;
128*9a747e4fSDavid du Colombier 			while(v & 3)
129*9a747e4fSDavid du Colombier 				v++;
130*9a747e4fSDavid du Colombier 			s->value = c;
131*9a747e4fSDavid du Colombier 			c += v;
132*9a747e4fSDavid du Colombier 		}
133*9a747e4fSDavid du Colombier 	}
134*9a747e4fSDavid du Colombier 
1357dd7cddfSDavid du Colombier 	c = rnd(c, 8);
1367dd7cddfSDavid du Colombier 
1377dd7cddfSDavid du Colombier 	setext = lookup("etext", 0);
1387dd7cddfSDavid du Colombier 	if(setext != S) {
1397dd7cddfSDavid du Colombier 		setext->value = c;
1407dd7cddfSDavid du Colombier 		textsize = c - INITTEXT;
1417dd7cddfSDavid du Colombier 	}
1427dd7cddfSDavid du Colombier 	if(INITRND)
1437dd7cddfSDavid du Colombier 		INITDAT = rnd(c, INITRND);
1447dd7cddfSDavid du Colombier 	if(debug['v'])
1457dd7cddfSDavid du Colombier 		Bprint(&bso, "tsize = %lux\n", textsize);
1467dd7cddfSDavid du Colombier 	Bflush(&bso);
1477dd7cddfSDavid du Colombier }
1487dd7cddfSDavid du Colombier 
1497dd7cddfSDavid du Colombier /*
1507dd7cddfSDavid du Colombier  * when the first reference to the literal pool threatens
1517dd7cddfSDavid du Colombier  * to go out of range of a 12-bit PC-relative offset,
1527dd7cddfSDavid du Colombier  * drop the pool now, and branch round it.
1537dd7cddfSDavid du Colombier  * this happens only in extended basic blocks that exceed 4k.
1547dd7cddfSDavid du Colombier  */
1557dd7cddfSDavid du Colombier void
1567dd7cddfSDavid du Colombier checkpool(Prog *p)
1577dd7cddfSDavid du Colombier {
1587dd7cddfSDavid du Colombier 	if(pool.size >= 0xffc || immaddr((p->pc+4)+4+pool.size - pool.start+8) == 0)
1597dd7cddfSDavid du Colombier 		flushpool(p, 1);
16059cc4ca5SDavid du Colombier 	else if(p->link == P)
16159cc4ca5SDavid du Colombier 		flushpool(p, 2);
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier 
1647dd7cddfSDavid du Colombier void
1657dd7cddfSDavid du Colombier flushpool(Prog *p, int skip)
1667dd7cddfSDavid du Colombier {
1677dd7cddfSDavid du Colombier 	Prog *q;
1687dd7cddfSDavid du Colombier 
1697dd7cddfSDavid du Colombier 	if(blitrl) {
1707dd7cddfSDavid du Colombier 		if(skip){
171*9a747e4fSDavid du Colombier 			if(debug['v'] && skip == 1)
172*9a747e4fSDavid du Colombier 				print("note: flush literal pool at %lux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start);
1737dd7cddfSDavid du Colombier 			q = prg();
1747dd7cddfSDavid du Colombier 			q->as = AB;
1757dd7cddfSDavid du Colombier 			q->to.type = D_BRANCH;
1767dd7cddfSDavid du Colombier 			q->cond = p->link;
1777dd7cddfSDavid du Colombier 			q->link = blitrl;
1787dd7cddfSDavid du Colombier 			blitrl = q;
1797dd7cddfSDavid du Colombier 		}
18059cc4ca5SDavid du Colombier 		else if(p->pc+pool.size-pool.start < 2048)
18159cc4ca5SDavid du Colombier 			return;
1827dd7cddfSDavid du Colombier 		elitrl->link = p->link;
1837dd7cddfSDavid du Colombier 		p->link = blitrl;
1847dd7cddfSDavid du Colombier 		blitrl = 0;	/* BUG: should refer back to values until out-of-range */
1857dd7cddfSDavid du Colombier 		elitrl = 0;
1867dd7cddfSDavid du Colombier 		pool.size = 0;
1877dd7cddfSDavid du Colombier 		pool.start = 0;
1887dd7cddfSDavid du Colombier 	}
1897dd7cddfSDavid du Colombier }
1907dd7cddfSDavid du Colombier 
1917dd7cddfSDavid du Colombier void
1927dd7cddfSDavid du Colombier addpool(Prog *p, Adr *a)
1937dd7cddfSDavid du Colombier {
1947dd7cddfSDavid du Colombier 	Prog *q, t;
1957dd7cddfSDavid du Colombier 	int c;
1967dd7cddfSDavid du Colombier 
1977dd7cddfSDavid du Colombier 	c = aclass(a);
1987dd7cddfSDavid du Colombier 
1997dd7cddfSDavid du Colombier 	t = zprg;
2007dd7cddfSDavid du Colombier 	t.as = AWORD;
2017dd7cddfSDavid du Colombier 
2027dd7cddfSDavid du Colombier 	switch(c) {
2037dd7cddfSDavid du Colombier 	default:
2047dd7cddfSDavid du Colombier 		t.to = *a;
2057dd7cddfSDavid du Colombier 		break;
20659cc4ca5SDavid du Colombier 
20759cc4ca5SDavid du Colombier 	case C_SROREG:
2087dd7cddfSDavid du Colombier 	case C_LOREG:
2097dd7cddfSDavid du Colombier 	case C_ROREG:
21059cc4ca5SDavid du Colombier 	case C_FOREG:
21159cc4ca5SDavid du Colombier 	case C_SOREG:
21259cc4ca5SDavid du Colombier 	case C_FAUTO:
21359cc4ca5SDavid du Colombier 	case C_SAUTO:
2147dd7cddfSDavid du Colombier 	case C_LAUTO:
2157dd7cddfSDavid du Colombier 	case C_LACON:
2167dd7cddfSDavid du Colombier 		t.to.type = D_CONST;
2177dd7cddfSDavid du Colombier 		t.to.offset = instoffset;
2187dd7cddfSDavid du Colombier 		break;
2197dd7cddfSDavid du Colombier 	}
2207dd7cddfSDavid du Colombier 
2217dd7cddfSDavid du Colombier 	for(q = blitrl; q != P; q = q->link)	/* could hash on t.t0.offset */
2227dd7cddfSDavid du Colombier 		if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
2237dd7cddfSDavid du Colombier 			p->cond = q;
2247dd7cddfSDavid du Colombier 			return;
2257dd7cddfSDavid du Colombier 		}
2267dd7cddfSDavid du Colombier 
2277dd7cddfSDavid du Colombier 	q = prg();
2287dd7cddfSDavid du Colombier 	*q = t;
2297dd7cddfSDavid du Colombier 	q->pc = pool.size;
2307dd7cddfSDavid du Colombier 
2317dd7cddfSDavid du Colombier 	if(blitrl == P) {
2327dd7cddfSDavid du Colombier 		blitrl = q;
2337dd7cddfSDavid du Colombier 		pool.start = p->pc;
2347dd7cddfSDavid du Colombier 	} else
2357dd7cddfSDavid du Colombier 		elitrl->link = q;
2367dd7cddfSDavid du Colombier 	elitrl = q;
2377dd7cddfSDavid du Colombier 	pool.size += 4;
2387dd7cddfSDavid du Colombier 
2397dd7cddfSDavid du Colombier 	p->cond = q;
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier 
2427dd7cddfSDavid du Colombier void
2437dd7cddfSDavid du Colombier xdefine(char *p, int t, long v)
2447dd7cddfSDavid du Colombier {
2457dd7cddfSDavid du Colombier 	Sym *s;
2467dd7cddfSDavid du Colombier 
2477dd7cddfSDavid du Colombier 	s = lookup(p, 0);
2487dd7cddfSDavid du Colombier 	if(s->type == 0 || s->type == SXREF) {
2497dd7cddfSDavid du Colombier 		s->type = t;
2507dd7cddfSDavid du Colombier 		s->value = v;
2517dd7cddfSDavid du Colombier 	}
2527dd7cddfSDavid du Colombier }
2537dd7cddfSDavid du Colombier 
2547dd7cddfSDavid du Colombier long
2557dd7cddfSDavid du Colombier regoff(Adr *a)
2567dd7cddfSDavid du Colombier {
2577dd7cddfSDavid du Colombier 
2587dd7cddfSDavid du Colombier 	instoffset = 0;
2597dd7cddfSDavid du Colombier 	aclass(a);
2607dd7cddfSDavid du Colombier 	return instoffset;
2617dd7cddfSDavid du Colombier }
2627dd7cddfSDavid du Colombier 
2637dd7cddfSDavid du Colombier long
2647dd7cddfSDavid du Colombier immrot(ulong v)
2657dd7cddfSDavid du Colombier {
2667dd7cddfSDavid du Colombier 	int i;
2677dd7cddfSDavid du Colombier 
2687dd7cddfSDavid du Colombier 	for(i=0; i<16; i++) {
2697dd7cddfSDavid du Colombier 		if((v & ~0xff) == 0)
2707dd7cddfSDavid du Colombier 			return (i<<8) | v | (1<<25);
2717dd7cddfSDavid du Colombier 		v = (v<<2) | (v>>30);
2727dd7cddfSDavid du Colombier 	}
2737dd7cddfSDavid du Colombier 	return 0;
2747dd7cddfSDavid du Colombier }
2757dd7cddfSDavid du Colombier 
2767dd7cddfSDavid du Colombier long
2777dd7cddfSDavid du Colombier immaddr(long v)
2787dd7cddfSDavid du Colombier {
2797dd7cddfSDavid du Colombier 	if(v >= 0 && v <= 0xfff)
2807dd7cddfSDavid du Colombier 		return (v & 0xfff) |
2817dd7cddfSDavid du Colombier 			(1<<24) |	/* pre indexing */
2827dd7cddfSDavid du Colombier 			(1<<23);	/* pre indexing, up */
2837dd7cddfSDavid du Colombier 	if(v >= -0xfff && v < 0)
2847dd7cddfSDavid du Colombier 		return (-v & 0xfff) |
2857dd7cddfSDavid du Colombier 			(1<<24);	/* pre indexing */
2867dd7cddfSDavid du Colombier 	return 0;
2877dd7cddfSDavid du Colombier }
2887dd7cddfSDavid du Colombier 
2897dd7cddfSDavid du Colombier int
2907dd7cddfSDavid du Colombier immfloat(long v)
2917dd7cddfSDavid du Colombier {
2927dd7cddfSDavid du Colombier 	return (v & 0xC03) == 0;	/* offset will fit in floating-point load/store */
2937dd7cddfSDavid du Colombier }
2947dd7cddfSDavid du Colombier 
2957dd7cddfSDavid du Colombier int
29659cc4ca5SDavid du Colombier immhalf(long v)
29759cc4ca5SDavid du Colombier {
29859cc4ca5SDavid du Colombier 	if(v >= 0 && v <= 0xff)
29959cc4ca5SDavid du Colombier 		return v|
30059cc4ca5SDavid du Colombier 			(1<<24)|	/* pre indexing */
30159cc4ca5SDavid du Colombier 			(1<<23);	/* pre indexing, up */
30259cc4ca5SDavid du Colombier 	if(v >= -0xff && v < 0)
30359cc4ca5SDavid du Colombier 		return (-v & 0xff)|
30459cc4ca5SDavid du Colombier 			(1<<24);	/* pre indexing */
30559cc4ca5SDavid du Colombier 	return 0;
30659cc4ca5SDavid du Colombier }
30759cc4ca5SDavid du Colombier 
30859cc4ca5SDavid du Colombier int
3097dd7cddfSDavid du Colombier aclass(Adr *a)
3107dd7cddfSDavid du Colombier {
3117dd7cddfSDavid du Colombier 	Sym *s;
3127dd7cddfSDavid du Colombier 	int t;
3137dd7cddfSDavid du Colombier 
3147dd7cddfSDavid du Colombier 	switch(a->type) {
3157dd7cddfSDavid du Colombier 	case D_NONE:
3167dd7cddfSDavid du Colombier 		return C_NONE;
3177dd7cddfSDavid du Colombier 
3187dd7cddfSDavid du Colombier 	case D_REG:
3197dd7cddfSDavid du Colombier 		return C_REG;
3207dd7cddfSDavid du Colombier 
32159cc4ca5SDavid du Colombier 	case D_REGREG:
32259cc4ca5SDavid du Colombier 		return C_REGREG;
32359cc4ca5SDavid du Colombier 
3247dd7cddfSDavid du Colombier 	case D_SHIFT:
3257dd7cddfSDavid du Colombier 		return C_SHIFT;
3267dd7cddfSDavid du Colombier 
3277dd7cddfSDavid du Colombier 	case D_FREG:
3287dd7cddfSDavid du Colombier 		return C_FREG;
3297dd7cddfSDavid du Colombier 
3307dd7cddfSDavid du Colombier 	case D_FPCR:
3317dd7cddfSDavid du Colombier 		return C_FCR;
3327dd7cddfSDavid du Colombier 
3337dd7cddfSDavid du Colombier 	case D_OREG:
3347dd7cddfSDavid du Colombier 		switch(a->name) {
3357dd7cddfSDavid du Colombier 		case D_EXTERN:
3367dd7cddfSDavid du Colombier 		case D_STATIC:
3377dd7cddfSDavid du Colombier 			if(a->sym == 0 || a->sym->name == 0) {
3387dd7cddfSDavid du Colombier 				print("null sym external\n");
3397dd7cddfSDavid du Colombier 				print("%D\n", a);
3407dd7cddfSDavid du Colombier 				return C_GOK;
3417dd7cddfSDavid du Colombier 			}
342*9a747e4fSDavid du Colombier 			s = a->sym;
343*9a747e4fSDavid du Colombier 			t = s->type;
3447dd7cddfSDavid du Colombier 			if(t == 0 || t == SXREF) {
3457dd7cddfSDavid du Colombier 				diag("undefined external: %s in %s\n",
346*9a747e4fSDavid du Colombier 					s->name, TNAME);
347*9a747e4fSDavid du Colombier 				s->type = SDATA;
3487dd7cddfSDavid du Colombier 			}
349*9a747e4fSDavid du Colombier 			if(reloc) {
350*9a747e4fSDavid du Colombier 				switch(t) {
351*9a747e4fSDavid du Colombier 				default:
352*9a747e4fSDavid du Colombier 					instoffset = s->value + a->offset + INITDAT;
353*9a747e4fSDavid du Colombier 					break;
354*9a747e4fSDavid du Colombier 				case STEXT:
355*9a747e4fSDavid du Colombier 					if(s->value == -1)
356*9a747e4fSDavid du Colombier 						undefsym(s);
357*9a747e4fSDavid du Colombier 				case SCONST:
358*9a747e4fSDavid du Colombier 				case SLEAF:
359*9a747e4fSDavid du Colombier 				case SSTRING:
360*9a747e4fSDavid du Colombier 					instoffset = s->value + a->offset;
361*9a747e4fSDavid du Colombier 					break;
362*9a747e4fSDavid du Colombier 				}
363*9a747e4fSDavid du Colombier 				return C_ADDR;
364*9a747e4fSDavid du Colombier 			}
365*9a747e4fSDavid du Colombier 			instoffset = s->value + a->offset - BIG;
3667dd7cddfSDavid du Colombier 			t = immaddr(instoffset);
3677dd7cddfSDavid du Colombier 			if(t) {
36859cc4ca5SDavid du Colombier 				if(immhalf(instoffset))
36959cc4ca5SDavid du Colombier 					return immfloat(t) ? C_HFEXT : C_HEXT;
3707dd7cddfSDavid du Colombier 				if(immfloat(t))
3717dd7cddfSDavid du Colombier 					return C_FEXT;
3727dd7cddfSDavid du Colombier 				return C_SEXT;
3737dd7cddfSDavid du Colombier 			}
3747dd7cddfSDavid du Colombier 			return C_LEXT;
3757dd7cddfSDavid du Colombier 		case D_AUTO:
3767dd7cddfSDavid du Colombier 			instoffset = autosize + a->offset;
3777dd7cddfSDavid du Colombier 			t = immaddr(instoffset);
3787dd7cddfSDavid du Colombier 			if(t){
37959cc4ca5SDavid du Colombier 				if(immhalf(instoffset))
38059cc4ca5SDavid du Colombier 					return immfloat(t) ? C_HFAUTO : C_HAUTO;
3817dd7cddfSDavid du Colombier 				if(immfloat(t))
3827dd7cddfSDavid du Colombier 					return C_FAUTO;
3837dd7cddfSDavid du Colombier 				return C_SAUTO;
3847dd7cddfSDavid du Colombier 			}
3857dd7cddfSDavid du Colombier 			return C_LAUTO;
3867dd7cddfSDavid du Colombier 
3877dd7cddfSDavid du Colombier 		case D_PARAM:
3887dd7cddfSDavid du Colombier 			instoffset = autosize + a->offset + 4L;
3897dd7cddfSDavid du Colombier 			t = immaddr(instoffset);
3907dd7cddfSDavid du Colombier 			if(t){
39159cc4ca5SDavid du Colombier 				if(immhalf(instoffset))
39259cc4ca5SDavid du Colombier 					return immfloat(t) ? C_HFAUTO : C_HAUTO;
3937dd7cddfSDavid du Colombier 				if(immfloat(t))
3947dd7cddfSDavid du Colombier 					return C_FAUTO;
3957dd7cddfSDavid du Colombier 				return C_SAUTO;
3967dd7cddfSDavid du Colombier 			}
3977dd7cddfSDavid du Colombier 			return C_LAUTO;
3987dd7cddfSDavid du Colombier 		case D_NONE:
3997dd7cddfSDavid du Colombier 			instoffset = a->offset;
4007dd7cddfSDavid du Colombier 			t = immaddr(instoffset);
4017dd7cddfSDavid du Colombier 			if(t) {
40259cc4ca5SDavid du Colombier 				if(immhalf(instoffset))		 /* n.b. that it will also satisfy immrot */
40359cc4ca5SDavid du Colombier 					return immfloat(t) ? C_HFOREG : C_HOREG;
4047dd7cddfSDavid du Colombier 				if(immfloat(t))
4057dd7cddfSDavid du Colombier 					return C_FOREG; /* n.b. that it will also satisfy immrot */
4067dd7cddfSDavid du Colombier 				t = immrot(instoffset);
4077dd7cddfSDavid du Colombier 				if(t)
40859cc4ca5SDavid du Colombier 					return C_SROREG;
40959cc4ca5SDavid du Colombier 				if(immhalf(instoffset))
41059cc4ca5SDavid du Colombier 					return C_HOREG;
4117dd7cddfSDavid du Colombier 				return C_SOREG;
4127dd7cddfSDavid du Colombier 			}
4137dd7cddfSDavid du Colombier 			t = immrot(instoffset);
4147dd7cddfSDavid du Colombier 			if(t)
4157dd7cddfSDavid du Colombier 				return C_ROREG;
4167dd7cddfSDavid du Colombier 			return C_LOREG;
4177dd7cddfSDavid du Colombier 		}
4187dd7cddfSDavid du Colombier 		return C_GOK;
4197dd7cddfSDavid du Colombier 
4207dd7cddfSDavid du Colombier 	case D_PSR:
4217dd7cddfSDavid du Colombier 		return C_PSR;
4227dd7cddfSDavid du Colombier 
4237dd7cddfSDavid du Colombier 	case D_OCONST:
4247dd7cddfSDavid du Colombier 		switch(a->name) {
4257dd7cddfSDavid du Colombier 		case D_EXTERN:
4267dd7cddfSDavid du Colombier 		case D_STATIC:
4277dd7cddfSDavid du Colombier 			s = a->sym;
4287dd7cddfSDavid du Colombier 			t = s->type;
4297dd7cddfSDavid du Colombier 			if(t == 0 || t == SXREF) {
4307dd7cddfSDavid du Colombier 				diag("undefined external: %s in %s\n",
4317dd7cddfSDavid du Colombier 					s->name, TNAME);
4327dd7cddfSDavid du Colombier 				s->type = SDATA;
4337dd7cddfSDavid du Colombier 			}
4347dd7cddfSDavid du Colombier 			instoffset = s->value + a->offset + INITDAT;
435*9a747e4fSDavid du Colombier 			if(s->type == STEXT || s->type == SLEAF) {
436*9a747e4fSDavid du Colombier 				if(s->value == -1)
437*9a747e4fSDavid du Colombier 					undefsym(s);
4387dd7cddfSDavid du Colombier 				instoffset = s->value + a->offset;
439*9a747e4fSDavid du Colombier 			}
4407dd7cddfSDavid du Colombier 			return C_LCON;
4417dd7cddfSDavid du Colombier 		}
4427dd7cddfSDavid du Colombier 		return C_GOK;
4437dd7cddfSDavid du Colombier 
4447dd7cddfSDavid du Colombier 	case D_FCONST:
4457dd7cddfSDavid du Colombier 		return C_FCON;
4467dd7cddfSDavid du Colombier 
4477dd7cddfSDavid du Colombier 	case D_CONST:
4487dd7cddfSDavid du Colombier 		switch(a->name) {
4497dd7cddfSDavid du Colombier 
4507dd7cddfSDavid du Colombier 		case D_NONE:
4517dd7cddfSDavid du Colombier 			instoffset = a->offset;
4527dd7cddfSDavid du Colombier 			if(a->reg != NREG)
4537dd7cddfSDavid du Colombier 				goto aconsize;
4547dd7cddfSDavid du Colombier 
4557dd7cddfSDavid du Colombier 			t = immrot(instoffset);
4567dd7cddfSDavid du Colombier 			if(t)
4577dd7cddfSDavid du Colombier 				return C_RCON;
4587dd7cddfSDavid du Colombier 			t = immrot(~instoffset);
4597dd7cddfSDavid du Colombier 			if(t)
4607dd7cddfSDavid du Colombier 				return C_NCON;
4617dd7cddfSDavid du Colombier 			return C_LCON;
4627dd7cddfSDavid du Colombier 
4637dd7cddfSDavid du Colombier 		case D_EXTERN:
4647dd7cddfSDavid du Colombier 		case D_STATIC:
4657dd7cddfSDavid du Colombier 			s = a->sym;
4667dd7cddfSDavid du Colombier 			if(s == S)
4677dd7cddfSDavid du Colombier 				break;
4687dd7cddfSDavid du Colombier 			t = s->type;
4697dd7cddfSDavid du Colombier 			switch(t) {
4707dd7cddfSDavid du Colombier 			case 0:
4717dd7cddfSDavid du Colombier 			case SXREF:
4727dd7cddfSDavid du Colombier 				diag("undefined external: %s in %s\n",
4737dd7cddfSDavid du Colombier 					s->name, TNAME);
4747dd7cddfSDavid du Colombier 				s->type = SDATA;
4757dd7cddfSDavid du Colombier 				break;
4767dd7cddfSDavid du Colombier 			case STEXT:
477*9a747e4fSDavid du Colombier 				if(s->value == -1)
478*9a747e4fSDavid du Colombier 					undefsym(s);
479*9a747e4fSDavid du Colombier 			case SSTRING:
480*9a747e4fSDavid du Colombier 			case SCONST:
4817dd7cddfSDavid du Colombier 			case SLEAF:
4827dd7cddfSDavid du Colombier 				instoffset = s->value + a->offset;
4837dd7cddfSDavid du Colombier 				return C_LCON;
4847dd7cddfSDavid du Colombier 			}
485*9a747e4fSDavid du Colombier 			if(!reloc) {
4867dd7cddfSDavid du Colombier 				instoffset = s->value + a->offset - BIG;
4877dd7cddfSDavid du Colombier 				t = immrot(instoffset);
4887dd7cddfSDavid du Colombier 				if(t && instoffset != 0)
4897dd7cddfSDavid du Colombier 					return C_RECON;
490*9a747e4fSDavid du Colombier 			}
4917dd7cddfSDavid du Colombier 			instoffset = s->value + a->offset + INITDAT;
4927dd7cddfSDavid du Colombier 			return C_LCON;
4937dd7cddfSDavid du Colombier 
4947dd7cddfSDavid du Colombier 		case D_AUTO:
4957dd7cddfSDavid du Colombier 			instoffset = autosize + a->offset;
4967dd7cddfSDavid du Colombier 			goto aconsize;
4977dd7cddfSDavid du Colombier 
4987dd7cddfSDavid du Colombier 		case D_PARAM:
4997dd7cddfSDavid du Colombier 			instoffset = autosize + a->offset + 4L;
5007dd7cddfSDavid du Colombier 		aconsize:
5017dd7cddfSDavid du Colombier 			t = immrot(instoffset);
5027dd7cddfSDavid du Colombier 			if(t)
5037dd7cddfSDavid du Colombier 				return C_RACON;
5047dd7cddfSDavid du Colombier 			return C_LACON;
5057dd7cddfSDavid du Colombier 		}
5067dd7cddfSDavid du Colombier 		return C_GOK;
5077dd7cddfSDavid du Colombier 
5087dd7cddfSDavid du Colombier 	case D_BRANCH:
5097dd7cddfSDavid du Colombier 		return C_SBRA;
5107dd7cddfSDavid du Colombier 	}
5117dd7cddfSDavid du Colombier 	return C_GOK;
5127dd7cddfSDavid du Colombier }
5137dd7cddfSDavid du Colombier 
5147dd7cddfSDavid du Colombier Optab*
5157dd7cddfSDavid du Colombier oplook(Prog *p)
5167dd7cddfSDavid du Colombier {
5177dd7cddfSDavid du Colombier 	int a1, a2, a3, r;
5187dd7cddfSDavid du Colombier 	char *c1, *c3;
5197dd7cddfSDavid du Colombier 	Optab *o, *e;
5207dd7cddfSDavid du Colombier 
5217dd7cddfSDavid du Colombier 	a1 = p->optab;
5227dd7cddfSDavid du Colombier 	if(a1)
5237dd7cddfSDavid du Colombier 		return optab+(a1-1);
5247dd7cddfSDavid du Colombier 	a1 = p->from.class;
5257dd7cddfSDavid du Colombier 	if(a1 == 0) {
5267dd7cddfSDavid du Colombier 		a1 = aclass(&p->from) + 1;
5277dd7cddfSDavid du Colombier 		p->from.class = a1;
5287dd7cddfSDavid du Colombier 	}
5297dd7cddfSDavid du Colombier 	a1--;
5307dd7cddfSDavid du Colombier 	a3 = p->to.class;
5317dd7cddfSDavid du Colombier 	if(a3 == 0) {
5327dd7cddfSDavid du Colombier 		a3 = aclass(&p->to) + 1;
5337dd7cddfSDavid du Colombier 		p->to.class = a3;
5347dd7cddfSDavid du Colombier 	}
5357dd7cddfSDavid du Colombier 	a3--;
5367dd7cddfSDavid du Colombier 	a2 = C_NONE;
5377dd7cddfSDavid du Colombier 	if(p->reg != NREG)
5387dd7cddfSDavid du Colombier 		a2 = C_REG;
5397dd7cddfSDavid du Colombier 	r = p->as;
5407dd7cddfSDavid du Colombier 	o = oprange[r].start;
5417dd7cddfSDavid du Colombier 	if(o == 0) {
5427dd7cddfSDavid du Colombier 		a1 = opcross[repop[r]][a1][a2][a3];
5437dd7cddfSDavid du Colombier 		if(a1) {
5447dd7cddfSDavid du Colombier 			p->optab = a1+1;
5457dd7cddfSDavid du Colombier 			return optab+a1;
5467dd7cddfSDavid du Colombier 		}
5477dd7cddfSDavid du Colombier 		o = oprange[r].stop; /* just generate an error */
5487dd7cddfSDavid du Colombier 	}
5497dd7cddfSDavid du Colombier 	if(0) {
5507dd7cddfSDavid du Colombier 		print("oplook %A %d %d %d\n",
5517dd7cddfSDavid du Colombier 			(int)p->as, a1, a2, a3);
5527dd7cddfSDavid du Colombier 		print("		%d %d\n", p->from.type, p->to.type);
5537dd7cddfSDavid du Colombier 	}
5547dd7cddfSDavid du Colombier 	e = oprange[r].stop;
5557dd7cddfSDavid du Colombier 	c1 = xcmp[a1];
5567dd7cddfSDavid du Colombier 	c3 = xcmp[a3];
5577dd7cddfSDavid du Colombier 	for(; o<e; o++)
5587dd7cddfSDavid du Colombier 		if(o->a2 == a2)
5597dd7cddfSDavid du Colombier 		if(c1[o->a1])
5607dd7cddfSDavid du Colombier 		if(c3[o->a3]) {
5617dd7cddfSDavid du Colombier 			p->optab = (o-optab)+1;
5627dd7cddfSDavid du Colombier 			return o;
5637dd7cddfSDavid du Colombier 		}
5647dd7cddfSDavid du Colombier 	diag("illegal combination %A %d %d %d\n",
5657dd7cddfSDavid du Colombier 		p->as, a1, a2, a3);
5667dd7cddfSDavid du Colombier 	prasm(p);
5677dd7cddfSDavid du Colombier 	if(o == 0)
5687dd7cddfSDavid du Colombier 		o = optab;
5697dd7cddfSDavid du Colombier 	return o;
5707dd7cddfSDavid du Colombier }
5717dd7cddfSDavid du Colombier 
5727dd7cddfSDavid du Colombier int
5737dd7cddfSDavid du Colombier cmp(int a, int b)
5747dd7cddfSDavid du Colombier {
5757dd7cddfSDavid du Colombier 
5767dd7cddfSDavid du Colombier 	if(a == b)
5777dd7cddfSDavid du Colombier 		return 1;
5787dd7cddfSDavid du Colombier 	switch(a) {
5797dd7cddfSDavid du Colombier 	case C_LCON:
5807dd7cddfSDavid du Colombier 		if(b == C_RCON || b == C_NCON)
5817dd7cddfSDavid du Colombier 			return 1;
5827dd7cddfSDavid du Colombier 		break;
5837dd7cddfSDavid du Colombier 	case C_LACON:
5847dd7cddfSDavid du Colombier 		if(b == C_RACON)
5857dd7cddfSDavid du Colombier 			return 1;
5867dd7cddfSDavid du Colombier 		break;
5877dd7cddfSDavid du Colombier 	case C_LECON:
5887dd7cddfSDavid du Colombier 		if(b == C_RECON)
5897dd7cddfSDavid du Colombier 			return 1;
5907dd7cddfSDavid du Colombier 		break;
59159cc4ca5SDavid du Colombier 
59259cc4ca5SDavid du Colombier 	case C_HFEXT:
59359cc4ca5SDavid du Colombier 		return b == C_HEXT || b == C_FEXT;
59459cc4ca5SDavid du Colombier 	case C_FEXT:
59559cc4ca5SDavid du Colombier 	case C_HEXT:
59659cc4ca5SDavid du Colombier 		return b == C_HFEXT;
5977dd7cddfSDavid du Colombier 	case C_SEXT:
59859cc4ca5SDavid du Colombier 		return cmp(C_HFEXT, b);
5997dd7cddfSDavid du Colombier 	case C_LEXT:
60059cc4ca5SDavid du Colombier 		return cmp(C_SEXT, b);
60159cc4ca5SDavid du Colombier 
60259cc4ca5SDavid du Colombier 	case C_HFAUTO:
60359cc4ca5SDavid du Colombier 		return b == C_HAUTO || b == C_FAUTO;
60459cc4ca5SDavid du Colombier 	case C_FAUTO:
60559cc4ca5SDavid du Colombier 	case C_HAUTO:
60659cc4ca5SDavid du Colombier 		return b == C_HFAUTO;
6077dd7cddfSDavid du Colombier 	case C_SAUTO:
60859cc4ca5SDavid du Colombier 		return cmp(C_HFAUTO, b);
6097dd7cddfSDavid du Colombier 	case C_LAUTO:
61059cc4ca5SDavid du Colombier 		return cmp(C_SAUTO, b);
61159cc4ca5SDavid du Colombier 
61259cc4ca5SDavid du Colombier 	case C_HFOREG:
61359cc4ca5SDavid du Colombier 		return b == C_HOREG || b == C_FOREG;
61459cc4ca5SDavid du Colombier 	case C_FOREG:
61559cc4ca5SDavid du Colombier 	case C_HOREG:
61659cc4ca5SDavid du Colombier 		return b == C_HFOREG;
61759cc4ca5SDavid du Colombier 	case C_SROREG:
61859cc4ca5SDavid du Colombier 		return cmp(C_SOREG, b) || cmp(C_ROREG, b);
6197dd7cddfSDavid du Colombier 	case C_SOREG:
6207dd7cddfSDavid du Colombier 	case C_ROREG:
62159cc4ca5SDavid du Colombier 		return b == C_SROREG || cmp(C_HFOREG, b);
62259cc4ca5SDavid du Colombier 	case C_LOREG:
62359cc4ca5SDavid du Colombier 		return cmp(C_SROREG, b);
62459cc4ca5SDavid du Colombier 
6257dd7cddfSDavid du Colombier 	case C_LBRA:
6267dd7cddfSDavid du Colombier 		if(b == C_SBRA)
6277dd7cddfSDavid du Colombier 			return 1;
6287dd7cddfSDavid du Colombier 		break;
6297dd7cddfSDavid du Colombier 	}
6307dd7cddfSDavid du Colombier 	return 0;
6317dd7cddfSDavid du Colombier }
6327dd7cddfSDavid du Colombier 
6337dd7cddfSDavid du Colombier int
6347dd7cddfSDavid du Colombier ocmp(const void *a1, const void *a2)
6357dd7cddfSDavid du Colombier {
6367dd7cddfSDavid du Colombier 	Optab *p1, *p2;
6377dd7cddfSDavid du Colombier 	int n;
6387dd7cddfSDavid du Colombier 
6397dd7cddfSDavid du Colombier 	p1 = (Optab*)a1;
6407dd7cddfSDavid du Colombier 	p2 = (Optab*)a2;
6417dd7cddfSDavid du Colombier 	n = p1->as - p2->as;
6427dd7cddfSDavid du Colombier 	if(n)
6437dd7cddfSDavid du Colombier 		return n;
64459cc4ca5SDavid du Colombier 	n = (p2->flag&V4) - (p1->flag&V4);	/* architecture version */
64559cc4ca5SDavid du Colombier 	if(n)
64659cc4ca5SDavid du Colombier 		return n;
6477dd7cddfSDavid du Colombier 	n = p1->a1 - p2->a1;
6487dd7cddfSDavid du Colombier 	if(n)
6497dd7cddfSDavid du Colombier 		return n;
6507dd7cddfSDavid du Colombier 	n = p1->a2 - p2->a2;
6517dd7cddfSDavid du Colombier 	if(n)
6527dd7cddfSDavid du Colombier 		return n;
6537dd7cddfSDavid du Colombier 	n = p1->a3 - p2->a3;
6547dd7cddfSDavid du Colombier 	if(n)
6557dd7cddfSDavid du Colombier 		return n;
6567dd7cddfSDavid du Colombier 	return 0;
6577dd7cddfSDavid du Colombier }
6587dd7cddfSDavid du Colombier 
6597dd7cddfSDavid du Colombier void
6607dd7cddfSDavid du Colombier buildop(void)
6617dd7cddfSDavid du Colombier {
6627dd7cddfSDavid du Colombier 	int i, n, r;
6637dd7cddfSDavid du Colombier 
66459cc4ca5SDavid du Colombier 	armv4 = !debug['h'];
66559cc4ca5SDavid du Colombier 	for(i=0; i<C_GOK; i++)
66659cc4ca5SDavid du Colombier 		for(n=0; n<C_GOK; n++)
6677dd7cddfSDavid du Colombier 			xcmp[i][n] = cmp(n, i);
6687dd7cddfSDavid du Colombier 	for(n=0; optab[n].as != AXXX; n++)
66959cc4ca5SDavid du Colombier 		if((optab[n].flag & V4) && !armv4) {
67059cc4ca5SDavid du Colombier 			optab[n].as = AXXX;
67159cc4ca5SDavid du Colombier 			break;
67259cc4ca5SDavid du Colombier 		}
6737dd7cddfSDavid du Colombier 	qsort(optab, n, sizeof(optab[0]), ocmp);
6747dd7cddfSDavid du Colombier 	for(i=0; i<n; i++) {
6757dd7cddfSDavid du Colombier 		r = optab[i].as;
6767dd7cddfSDavid du Colombier 		oprange[r].start = optab+i;
6777dd7cddfSDavid du Colombier 		while(optab[i].as == r)
6787dd7cddfSDavid du Colombier 			i++;
6797dd7cddfSDavid du Colombier 		oprange[r].stop = optab+i;
6807dd7cddfSDavid du Colombier 		i--;
6817dd7cddfSDavid du Colombier 
6827dd7cddfSDavid du Colombier 		switch(r)
6837dd7cddfSDavid du Colombier 		{
6847dd7cddfSDavid du Colombier 		default:
6857dd7cddfSDavid du Colombier 			diag("unknown op in build: %A\n", r);
6867dd7cddfSDavid du Colombier 			errorexit();
6877dd7cddfSDavid du Colombier 		case AADD:
6887dd7cddfSDavid du Colombier 			oprange[AAND] = oprange[r];
6897dd7cddfSDavid du Colombier 			oprange[AEOR] = oprange[r];
6907dd7cddfSDavid du Colombier 			oprange[ASUB] = oprange[r];
6917dd7cddfSDavid du Colombier 			oprange[ARSB] = oprange[r];
6927dd7cddfSDavid du Colombier 			oprange[AADC] = oprange[r];
6937dd7cddfSDavid du Colombier 			oprange[ASBC] = oprange[r];
6947dd7cddfSDavid du Colombier 			oprange[ARSC] = oprange[r];
6957dd7cddfSDavid du Colombier 			oprange[AORR] = oprange[r];
6967dd7cddfSDavid du Colombier 			oprange[ABIC] = oprange[r];
6977dd7cddfSDavid du Colombier 			break;
6987dd7cddfSDavid du Colombier 		case ACMP:
6997dd7cddfSDavid du Colombier 			oprange[ATST] = oprange[r];
7007dd7cddfSDavid du Colombier 			oprange[ATEQ] = oprange[r];
7017dd7cddfSDavid du Colombier 			oprange[ACMN] = oprange[r];
7027dd7cddfSDavid du Colombier 			break;
7037dd7cddfSDavid du Colombier 		case AMVN:
7047dd7cddfSDavid du Colombier 			break;
7057dd7cddfSDavid du Colombier 		case ABEQ:
7067dd7cddfSDavid du Colombier 			oprange[ABNE] = oprange[r];
7077dd7cddfSDavid du Colombier 			oprange[ABCS] = oprange[r];
7087dd7cddfSDavid du Colombier 			oprange[ABHS] = oprange[r];
7097dd7cddfSDavid du Colombier 			oprange[ABCC] = oprange[r];
7107dd7cddfSDavid du Colombier 			oprange[ABLO] = oprange[r];
7117dd7cddfSDavid du Colombier 			oprange[ABMI] = oprange[r];
7127dd7cddfSDavid du Colombier 			oprange[ABPL] = oprange[r];
7137dd7cddfSDavid du Colombier 			oprange[ABVS] = oprange[r];
7147dd7cddfSDavid du Colombier 			oprange[ABVC] = oprange[r];
7157dd7cddfSDavid du Colombier 			oprange[ABHI] = oprange[r];
7167dd7cddfSDavid du Colombier 			oprange[ABLS] = oprange[r];
7177dd7cddfSDavid du Colombier 			oprange[ABGE] = oprange[r];
7187dd7cddfSDavid du Colombier 			oprange[ABLT] = oprange[r];
7197dd7cddfSDavid du Colombier 			oprange[ABGT] = oprange[r];
7207dd7cddfSDavid du Colombier 			oprange[ABLE] = oprange[r];
7217dd7cddfSDavid du Colombier 			break;
7227dd7cddfSDavid du Colombier 		case ASLL:
7237dd7cddfSDavid du Colombier 			oprange[ASRL] = oprange[r];
7247dd7cddfSDavid du Colombier 			oprange[ASRA] = oprange[r];
7257dd7cddfSDavid du Colombier 			break;
7267dd7cddfSDavid du Colombier 		case AMUL:
7277dd7cddfSDavid du Colombier 			oprange[AMULU] = oprange[r];
7287dd7cddfSDavid du Colombier 			break;
7297dd7cddfSDavid du Colombier 		case ADIV:
7307dd7cddfSDavid du Colombier 			oprange[AMOD] = oprange[r];
7317dd7cddfSDavid du Colombier 			oprange[AMODU] = oprange[r];
7327dd7cddfSDavid du Colombier 			oprange[ADIVU] = oprange[r];
7337dd7cddfSDavid du Colombier 			break;
7347dd7cddfSDavid du Colombier 		case AMOVW:
7357dd7cddfSDavid du Colombier 		case AMOVB:
7367dd7cddfSDavid du Colombier 		case AMOVBU:
7377dd7cddfSDavid du Colombier 		case AMOVH:
7387dd7cddfSDavid du Colombier 		case AMOVHU:
7397dd7cddfSDavid du Colombier 			break;
7407dd7cddfSDavid du Colombier 		case ASWPW:
7417dd7cddfSDavid du Colombier 			oprange[ASWPBU] = oprange[r];
7427dd7cddfSDavid du Colombier 			break;
7437dd7cddfSDavid du Colombier 		case AB:
7447dd7cddfSDavid du Colombier 		case ABL:
7457dd7cddfSDavid du Colombier 		case ASWI:
7467dd7cddfSDavid du Colombier 		case AWORD:
7477dd7cddfSDavid du Colombier 		case AMOVM:
7487dd7cddfSDavid du Colombier 		case ARFE:
7497dd7cddfSDavid du Colombier 		case ATEXT:
7507dd7cddfSDavid du Colombier 		case ACASE:
7517dd7cddfSDavid du Colombier 		case ABCASE:
7527dd7cddfSDavid du Colombier 			break;
7537dd7cddfSDavid du Colombier 		case AADDF:
7547dd7cddfSDavid du Colombier 			oprange[AADDD] = oprange[r];
7557dd7cddfSDavid du Colombier 			oprange[ASUBF] = oprange[r];
7567dd7cddfSDavid du Colombier 			oprange[ASUBD] = oprange[r];
7577dd7cddfSDavid du Colombier 			oprange[AMULF] = oprange[r];
7587dd7cddfSDavid du Colombier 			oprange[AMULD] = oprange[r];
7597dd7cddfSDavid du Colombier 			oprange[ADIVF] = oprange[r];
7607dd7cddfSDavid du Colombier 			oprange[ADIVD] = oprange[r];
7617dd7cddfSDavid du Colombier 			oprange[AMOVFD] = oprange[r];
7627dd7cddfSDavid du Colombier 			oprange[AMOVDF] = oprange[r];
7637dd7cddfSDavid du Colombier 			break;
7647dd7cddfSDavid du Colombier 
7657dd7cddfSDavid du Colombier 		case ACMPF:
7667dd7cddfSDavid du Colombier 			oprange[ACMPD] = oprange[r];
7677dd7cddfSDavid du Colombier 			break;
7687dd7cddfSDavid du Colombier 
7697dd7cddfSDavid du Colombier 		case AMOVF:
7707dd7cddfSDavid du Colombier 			oprange[AMOVD] = oprange[r];
7717dd7cddfSDavid du Colombier 			break;
7727dd7cddfSDavid du Colombier 
7737dd7cddfSDavid du Colombier 		case AMOVFW:
7747dd7cddfSDavid du Colombier 			oprange[AMOVWF] = oprange[r];
7757dd7cddfSDavid du Colombier 			oprange[AMOVWD] = oprange[r];
7767dd7cddfSDavid du Colombier 			oprange[AMOVDW] = oprange[r];
7777dd7cddfSDavid du Colombier 			break;
77859cc4ca5SDavid du Colombier 
77959cc4ca5SDavid du Colombier 		case AMULL:
78080ee5cbfSDavid du Colombier 			oprange[AMULA] = oprange[r];
78159cc4ca5SDavid du Colombier 			oprange[AMULAL] = oprange[r];
78259cc4ca5SDavid du Colombier 			oprange[AMULLU] = oprange[r];
78359cc4ca5SDavid du Colombier 			oprange[AMULALU] = oprange[r];
78459cc4ca5SDavid du Colombier 			break;
7857dd7cddfSDavid du Colombier 		}
7867dd7cddfSDavid du Colombier 	}
7877dd7cddfSDavid du Colombier }
7887dd7cddfSDavid du Colombier 
78959cc4ca5SDavid du Colombier /*
7907dd7cddfSDavid du Colombier void
7917dd7cddfSDavid du Colombier buildrep(int x, int as)
7927dd7cddfSDavid du Colombier {
7937dd7cddfSDavid du Colombier 	Opcross *p;
7947dd7cddfSDavid du Colombier 	Optab *e, *s, *o;
7957dd7cddfSDavid du Colombier 	int a1, a2, a3, n;
7967dd7cddfSDavid du Colombier 
7977dd7cddfSDavid du Colombier 	if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
7987dd7cddfSDavid du Colombier 		diag("assumptions fail in buildrep");
7997dd7cddfSDavid du Colombier 		errorexit();
8007dd7cddfSDavid du Colombier 	}
8017dd7cddfSDavid du Colombier 	repop[as] = x;
8027dd7cddfSDavid du Colombier 	p = (opcross + x);
8037dd7cddfSDavid du Colombier 	s = oprange[as].start;
8047dd7cddfSDavid du Colombier 	e = oprange[as].stop;
8057dd7cddfSDavid du Colombier 	for(o=e-1; o>=s; o--) {
8067dd7cddfSDavid du Colombier 		n = o-optab;
8077dd7cddfSDavid du Colombier 		for(a2=0; a2<2; a2++) {
8087dd7cddfSDavid du Colombier 			if(a2) {
8097dd7cddfSDavid du Colombier 				if(o->a2 == C_NONE)
8107dd7cddfSDavid du Colombier 					continue;
8117dd7cddfSDavid du Colombier 			} else
8127dd7cddfSDavid du Colombier 				if(o->a2 != C_NONE)
8137dd7cddfSDavid du Colombier 					continue;
8147dd7cddfSDavid du Colombier 			for(a1=0; a1<32; a1++) {
8157dd7cddfSDavid du Colombier 				if(!xcmp[a1][o->a1])
8167dd7cddfSDavid du Colombier 					continue;
8177dd7cddfSDavid du Colombier 				for(a3=0; a3<32; a3++)
8187dd7cddfSDavid du Colombier 					if(xcmp[a3][o->a3])
8197dd7cddfSDavid du Colombier 						(*p)[a1][a2][a3] = n;
8207dd7cddfSDavid du Colombier 			}
8217dd7cddfSDavid du Colombier 		}
8227dd7cddfSDavid du Colombier 	}
8237dd7cddfSDavid du Colombier 	oprange[as].start = 0;
8247dd7cddfSDavid du Colombier }
82559cc4ca5SDavid du Colombier */
826