xref: /plan9/sys/src/cmd/ql/span.c (revision 6891d8578618fb7ccda4a131c122d4d0e6580c4b)
17dd7cddfSDavid du Colombier #include	"l.h"
2375daca8SDavid du Colombier #define	r0iszero	1
37dd7cddfSDavid du Colombier 
47dd7cddfSDavid du Colombier void
span(void)57dd7cddfSDavid du Colombier span(void)
67dd7cddfSDavid du Colombier {
7*6891d857SDavid du Colombier 	Prog *p, *q;
87dd7cddfSDavid du Colombier 	Sym *setext;
97dd7cddfSDavid du Colombier 	Optab *o;
10*6891d857SDavid du Colombier 	int m, bflag;
11*6891d857SDavid du Colombier 	long c, otxt;
127dd7cddfSDavid du Colombier 
137dd7cddfSDavid du Colombier 	if(debug['v'])
147dd7cddfSDavid du Colombier 		Bprint(&bso, "%5.2f span\n", cputime());
157dd7cddfSDavid du Colombier 	Bflush(&bso);
16*6891d857SDavid du Colombier 
17*6891d857SDavid du Colombier 	bflag = 0;
187dd7cddfSDavid du Colombier 	c = INITTEXT;
19*6891d857SDavid du Colombier 	otxt = c;
207dd7cddfSDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
217dd7cddfSDavid du Colombier 		p->pc = c;
227dd7cddfSDavid du Colombier 		o = oplook(p);
237dd7cddfSDavid du Colombier 		m = o->size;
247dd7cddfSDavid du Colombier 		if(m == 0) {
257dd7cddfSDavid du Colombier 			if(p->as == ATEXT) {
267dd7cddfSDavid du Colombier 				curtext = p;
277dd7cddfSDavid du Colombier 				autosize = p->to.offset + 4;
287dd7cddfSDavid du Colombier 				if(p->from3.type == D_CONST) {
297dd7cddfSDavid du Colombier 					if(p->from3.offset & 3)
307dd7cddfSDavid du Colombier 						diag("illegal origin\n%P", p);
317dd7cddfSDavid du Colombier 					if(c > p->from3.offset)
327dd7cddfSDavid du Colombier 						diag("passed origin (#%lux)\n%P", c, p);
337dd7cddfSDavid du Colombier 					else
347dd7cddfSDavid du Colombier 						c = p->from3.offset;
357dd7cddfSDavid du Colombier 					p->pc = c;
367dd7cddfSDavid du Colombier 				}
377dd7cddfSDavid du Colombier 				if(p->from.sym != S)
387dd7cddfSDavid du Colombier 					p->from.sym->value = c;
39*6891d857SDavid du Colombier 				/* need passes to resolve branches? */
40*6891d857SDavid du Colombier 				if(c-otxt >= (1L<<15))
41*6891d857SDavid du Colombier 					bflag = c;
42*6891d857SDavid du Colombier 				otxt = c;
437dd7cddfSDavid du Colombier 				continue;
447dd7cddfSDavid du Colombier 			}
457dd7cddfSDavid du Colombier 			if(p->as != ANOP)
466b6b9ac8SDavid du Colombier 				diag("zero-width instruction\n%P", p);
477dd7cddfSDavid du Colombier 			continue;
487dd7cddfSDavid du Colombier 		}
497dd7cddfSDavid du Colombier 		c += m;
507dd7cddfSDavid du Colombier 	}
51*6891d857SDavid du Colombier 
52*6891d857SDavid du Colombier 	/*
53*6891d857SDavid du Colombier 	 * if any procedure is large enough to
54*6891d857SDavid du Colombier 	 * generate a large SBRA branch, then
55*6891d857SDavid du Colombier 	 * generate extra passes putting branches
56*6891d857SDavid du Colombier 	 * around jmps to fix. this is rare.
57*6891d857SDavid du Colombier 	 */
58*6891d857SDavid du Colombier 	while(bflag) {
59*6891d857SDavid du Colombier 		if(debug['v'])
60*6891d857SDavid du Colombier 			Bprint(&bso, "%5.2f span1\n", cputime());
61*6891d857SDavid du Colombier 		bflag = 0;
62*6891d857SDavid du Colombier 		c = INITTEXT;
63*6891d857SDavid du Colombier 		for(p = firstp; p != P; p = p->link) {
64*6891d857SDavid du Colombier 			p->pc = c;
65*6891d857SDavid du Colombier 			o = oplook(p);
66*6891d857SDavid du Colombier 			if((o->type == 16 || o->type == 17) && p->cond) {
67*6891d857SDavid du Colombier 				otxt = p->cond->pc - c;
68*6891d857SDavid du Colombier 				if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
69*6891d857SDavid du Colombier 					q = prg();
70*6891d857SDavid du Colombier 					q->link = p->link;
71*6891d857SDavid du Colombier 					p->link = q;
72*6891d857SDavid du Colombier 					q->as = ABR;
73*6891d857SDavid du Colombier 					q->to.type = D_BRANCH;
74*6891d857SDavid du Colombier 					q->cond = p->cond;
75*6891d857SDavid du Colombier 					p->cond = q;
76*6891d857SDavid du Colombier 					q = prg();
77*6891d857SDavid du Colombier 					q->link = p->link;
78*6891d857SDavid du Colombier 					p->link = q;
79*6891d857SDavid du Colombier 					q->as = ABR;
80*6891d857SDavid du Colombier 					q->to.type = D_BRANCH;
81*6891d857SDavid du Colombier 					q->cond = q->link->link;
82*6891d857SDavid du Colombier 					addnop(p->link);
83*6891d857SDavid du Colombier 					addnop(p);
84*6891d857SDavid du Colombier 					bflag = 1;
85*6891d857SDavid du Colombier 				}
86*6891d857SDavid du Colombier 			}
87*6891d857SDavid du Colombier 			m = o->size;
88*6891d857SDavid du Colombier 			if(m == 0) {
89*6891d857SDavid du Colombier 				if(p->as == ATEXT) {
90*6891d857SDavid du Colombier 					curtext = p;
91*6891d857SDavid du Colombier 					autosize = p->to.offset + 4;
92*6891d857SDavid du Colombier 					if(p->from.sym != S)
93*6891d857SDavid du Colombier 						p->from.sym->value = c;
94*6891d857SDavid du Colombier 					continue;
95*6891d857SDavid du Colombier 				}
96*6891d857SDavid du Colombier 				if(p->as != ANOP)
97*6891d857SDavid du Colombier 					diag("zero-width instruction\n%P", p);
98*6891d857SDavid du Colombier 				continue;
99*6891d857SDavid du Colombier 			}
100*6891d857SDavid du Colombier 			c += m;
101*6891d857SDavid du Colombier 		}
102*6891d857SDavid du Colombier 	}
103*6891d857SDavid du Colombier 
104*6891d857SDavid du Colombier 	c = rnd(c, 8);
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier 	setext = lookup("etext", 0);
1077dd7cddfSDavid du Colombier 	if(setext != S) {
1087dd7cddfSDavid du Colombier 		setext->value = c;
1097dd7cddfSDavid du Colombier 		textsize = c - INITTEXT;
1107dd7cddfSDavid du Colombier 	}
1117dd7cddfSDavid du Colombier 	if(INITRND)
1127dd7cddfSDavid du Colombier 		INITDAT = rnd(c, INITRND);
1137dd7cddfSDavid du Colombier 	if(debug['v'])
1147dd7cddfSDavid du Colombier 		Bprint(&bso, "tsize = %lux\n", textsize);
1157dd7cddfSDavid du Colombier 	Bflush(&bso);
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier 
1187dd7cddfSDavid du Colombier void
xdefine(char * p,int t,long v)1197dd7cddfSDavid du Colombier xdefine(char *p, int t, long v)
1207dd7cddfSDavid du Colombier {
1217dd7cddfSDavid du Colombier 	Sym *s;
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier 	s = lookup(p, 0);
1247dd7cddfSDavid du Colombier 	if(s->type == 0 || s->type == SXREF) {
1257dd7cddfSDavid du Colombier 		s->type = t;
1267dd7cddfSDavid du Colombier 		s->value = v;
1277dd7cddfSDavid du Colombier 	}
1287dd7cddfSDavid du Colombier }
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier long
regoff(Adr * a)1317dd7cddfSDavid du Colombier regoff(Adr *a)
1327dd7cddfSDavid du Colombier {
1337dd7cddfSDavid du Colombier 
134375daca8SDavid du Colombier 	instoffset = 0;
1357dd7cddfSDavid du Colombier 	aclass(a);
136375daca8SDavid du Colombier 	return instoffset;
1377dd7cddfSDavid du Colombier }
1387dd7cddfSDavid du Colombier 
1397dd7cddfSDavid du Colombier int
aclass(Adr * a)1407dd7cddfSDavid du Colombier aclass(Adr *a)
1417dd7cddfSDavid du Colombier {
1427dd7cddfSDavid du Colombier 	Sym *s;
1437dd7cddfSDavid du Colombier 	int t;
1447dd7cddfSDavid du Colombier 
1457dd7cddfSDavid du Colombier 	switch(a->type) {
1467dd7cddfSDavid du Colombier 	case D_NONE:
1477dd7cddfSDavid du Colombier 		return C_NONE;
1487dd7cddfSDavid du Colombier 
1497dd7cddfSDavid du Colombier 	case D_REG:
1507dd7cddfSDavid du Colombier 		return C_REG;
1517dd7cddfSDavid du Colombier 
1527dd7cddfSDavid du Colombier 	case D_FREG:
1537dd7cddfSDavid du Colombier 		return C_FREG;
1547dd7cddfSDavid du Colombier 
1557dd7cddfSDavid du Colombier 	case D_CREG:
1567dd7cddfSDavid du Colombier 		return C_CREG;
1577dd7cddfSDavid du Colombier 
1587dd7cddfSDavid du Colombier 	case D_SPR:
1597dd7cddfSDavid du Colombier 		if(a->offset == D_LR)
1607dd7cddfSDavid du Colombier 			return C_LR;
1617dd7cddfSDavid du Colombier 		if(a->offset == D_XER)
1627dd7cddfSDavid du Colombier 			return C_XER;
1637dd7cddfSDavid du Colombier 		if(a->offset == D_CTR)
1647dd7cddfSDavid du Colombier 			return C_CTR;
1657dd7cddfSDavid du Colombier 		return C_SPR;
1667dd7cddfSDavid du Colombier 
167375daca8SDavid du Colombier 	case D_DCR:
168375daca8SDavid du Colombier 		return C_SPR;
169375daca8SDavid du Colombier 
1707dd7cddfSDavid du Colombier 	case D_SREG:
1717dd7cddfSDavid du Colombier 		return C_SREG;
1727dd7cddfSDavid du Colombier 
1737dd7cddfSDavid du Colombier 	case D_FPSCR:
1747dd7cddfSDavid du Colombier 		return C_FPSCR;
1757dd7cddfSDavid du Colombier 
1767dd7cddfSDavid du Colombier 	case D_MSR:
1777dd7cddfSDavid du Colombier 		return C_MSR;
1787dd7cddfSDavid du Colombier 
1797dd7cddfSDavid du Colombier 	case D_OREG:
1807dd7cddfSDavid du Colombier 		switch(a->name) {
1817dd7cddfSDavid du Colombier 		case D_EXTERN:
1827dd7cddfSDavid du Colombier 		case D_STATIC:
1837dd7cddfSDavid du Colombier 			if(a->sym == S)
1847dd7cddfSDavid du Colombier 				break;
1857dd7cddfSDavid du Colombier 			t = a->sym->type;
1867dd7cddfSDavid du Colombier 			if(t == 0 || t == SXREF) {
1876b6b9ac8SDavid du Colombier 				diag("undefined external: %s in %s",
1887dd7cddfSDavid du Colombier 					a->sym->name, TNAME);
1897dd7cddfSDavid du Colombier 				a->sym->type = SDATA;
1907dd7cddfSDavid du Colombier 			}
191375daca8SDavid du Colombier 			if(dlm){
192375daca8SDavid du Colombier 				instoffset = a->sym->value + a->offset;
193375daca8SDavid du Colombier 				switch(a->sym->type){
194375daca8SDavid du Colombier 				case STEXT:
195375daca8SDavid du Colombier 				case SLEAF:
196375daca8SDavid du Colombier 				case SCONST:
197375daca8SDavid du Colombier 				case SUNDEF:
198375daca8SDavid du Colombier 					break;
199375daca8SDavid du Colombier 				default:
200375daca8SDavid du Colombier 					instoffset += INITDAT;
201375daca8SDavid du Colombier 				}
202375daca8SDavid du Colombier 				return C_ADDR;
203375daca8SDavid du Colombier 			}
204375daca8SDavid du Colombier 			instoffset = a->sym->value + a->offset - BIG;
205375daca8SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
2067dd7cddfSDavid du Colombier 				return C_SEXT;
2077dd7cddfSDavid du Colombier 			return C_LEXT;
2087dd7cddfSDavid du Colombier 		case D_AUTO:
209375daca8SDavid du Colombier 			instoffset = autosize + a->offset;
210375daca8SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
2117dd7cddfSDavid du Colombier 				return C_SAUTO;
2127dd7cddfSDavid du Colombier 			return C_LAUTO;
2137dd7cddfSDavid du Colombier 
2147dd7cddfSDavid du Colombier 		case D_PARAM:
215375daca8SDavid du Colombier 			instoffset = autosize + a->offset + 4L;
216375daca8SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
2177dd7cddfSDavid du Colombier 				return C_SAUTO;
2187dd7cddfSDavid du Colombier 			return C_LAUTO;
2197dd7cddfSDavid du Colombier 		case D_NONE:
220375daca8SDavid du Colombier 			instoffset = a->offset;
221375daca8SDavid du Colombier 			if(instoffset == 0)
2227dd7cddfSDavid du Colombier 				return C_ZOREG;
223375daca8SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
2247dd7cddfSDavid du Colombier 				return C_SOREG;
2257dd7cddfSDavid du Colombier 			return C_LOREG;
2267dd7cddfSDavid du Colombier 		}
2277dd7cddfSDavid du Colombier 		return C_GOK;
2287dd7cddfSDavid du Colombier 
2297dd7cddfSDavid du Colombier 	case D_OPT:
230375daca8SDavid du Colombier 		instoffset = a->offset & 31L;
2317dd7cddfSDavid du Colombier 		if(a->name == D_NONE)
2327dd7cddfSDavid du Colombier 			return C_SCON;
2337dd7cddfSDavid du Colombier 		return C_GOK;
2347dd7cddfSDavid du Colombier 
2357dd7cddfSDavid du Colombier 	case D_CONST:
2367dd7cddfSDavid du Colombier 		switch(a->name) {
2377dd7cddfSDavid du Colombier 
2387dd7cddfSDavid du Colombier 		case D_NONE:
239375daca8SDavid du Colombier 			instoffset = a->offset;
2407dd7cddfSDavid du Colombier 		consize:
241375daca8SDavid du Colombier 			if(instoffset >= 0) {
242375daca8SDavid du Colombier 				if(r0iszero && instoffset == 0)
243375daca8SDavid du Colombier 					return C_ZCON;
244375daca8SDavid du Colombier 				if(instoffset <= 0x7fff)
2457dd7cddfSDavid du Colombier 					return C_SCON;
246375daca8SDavid du Colombier 				if(instoffset <= 0xffff)
2477dd7cddfSDavid du Colombier 					return C_ANDCON;
248375daca8SDavid du Colombier 				if((instoffset & 0xffff) == 0)
2497dd7cddfSDavid du Colombier 					return C_UCON;
2507dd7cddfSDavid du Colombier 				return C_LCON;
2517dd7cddfSDavid du Colombier 			}
252375daca8SDavid du Colombier 			if(instoffset >= -0x8000)
2537dd7cddfSDavid du Colombier 				return C_ADDCON;
254375daca8SDavid du Colombier 			if((instoffset & 0xffff) == 0)
2557dd7cddfSDavid du Colombier 				return C_UCON;
2567dd7cddfSDavid du Colombier 			return C_LCON;
2577dd7cddfSDavid du Colombier 
2587dd7cddfSDavid du Colombier 		case D_EXTERN:
2597dd7cddfSDavid du Colombier 		case D_STATIC:
2607dd7cddfSDavid du Colombier 			s = a->sym;
2617dd7cddfSDavid du Colombier 			if(s == S)
2627dd7cddfSDavid du Colombier 				break;
2637dd7cddfSDavid du Colombier 			t = s->type;
2647dd7cddfSDavid du Colombier 			if(t == 0 || t == SXREF) {
2656b6b9ac8SDavid du Colombier 				diag("undefined external: %s in %s",
2667dd7cddfSDavid du Colombier 					s->name, TNAME);
2677dd7cddfSDavid du Colombier 				s->type = SDATA;
2687dd7cddfSDavid du Colombier 			}
269375daca8SDavid du Colombier 			if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
270375daca8SDavid du Colombier 				instoffset = s->value + a->offset;
2717dd7cddfSDavid du Colombier 				return C_LCON;
2727dd7cddfSDavid du Colombier 			}
2737dd7cddfSDavid du Colombier 			if(s->type == SCONST) {
274375daca8SDavid du Colombier 				instoffset = s->value + a->offset;
275375daca8SDavid du Colombier 				if(dlm)
276375daca8SDavid du Colombier 					return C_LCON;
2777dd7cddfSDavid du Colombier 				goto consize;
2787dd7cddfSDavid du Colombier 			}
279375daca8SDavid du Colombier 			if(!dlm){
280375daca8SDavid du Colombier 				instoffset = s->value + a->offset - BIG;
281375daca8SDavid du Colombier 				if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
2827dd7cddfSDavid du Colombier 					return C_SECON;
283375daca8SDavid du Colombier 			}
284375daca8SDavid du Colombier 			instoffset = s->value + a->offset + INITDAT;
285375daca8SDavid du Colombier 			if(dlm)
286375daca8SDavid du Colombier 				return C_LCON;
2877dd7cddfSDavid du Colombier 			/* not sure why this barfs */
2887dd7cddfSDavid du Colombier 			return C_LCON;
289b85a8364SDavid du Colombier 		/*
290375daca8SDavid du Colombier 			if(instoffset == 0)
2917dd7cddfSDavid du Colombier 				return C_ZCON;
292375daca8SDavid du Colombier 			if(instoffset >= -0x8000 && instoffset <= 0xffff)
2937dd7cddfSDavid du Colombier 				return C_SCON;
294375daca8SDavid du Colombier 			if((instoffset & 0xffff) == 0)
2957dd7cddfSDavid du Colombier 				return C_UCON;
2967dd7cddfSDavid du Colombier 			return C_LCON;
297b85a8364SDavid du Colombier 		*/
2987dd7cddfSDavid du Colombier 
2997dd7cddfSDavid du Colombier 		case D_AUTO:
300375daca8SDavid du Colombier 			instoffset = autosize + a->offset;
301375daca8SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
3027dd7cddfSDavid du Colombier 				return C_SACON;
3037dd7cddfSDavid du Colombier 			return C_LACON;
3047dd7cddfSDavid du Colombier 
3057dd7cddfSDavid du Colombier 		case D_PARAM:
306375daca8SDavid du Colombier 			instoffset = autosize + a->offset + 4L;
307375daca8SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
3087dd7cddfSDavid du Colombier 				return C_SACON;
3097dd7cddfSDavid du Colombier 			return C_LACON;
3107dd7cddfSDavid du Colombier 		}
3117dd7cddfSDavid du Colombier 		return C_GOK;
3127dd7cddfSDavid du Colombier 
3137dd7cddfSDavid du Colombier 	case D_BRANCH:
3147dd7cddfSDavid du Colombier 		return C_SBRA;
3157dd7cddfSDavid du Colombier 	}
3167dd7cddfSDavid du Colombier 	return C_GOK;
3177dd7cddfSDavid du Colombier }
3187dd7cddfSDavid du Colombier 
3197dd7cddfSDavid du Colombier Optab*
oplook(Prog * p)3207dd7cddfSDavid du Colombier oplook(Prog *p)
3217dd7cddfSDavid du Colombier {
3227dd7cddfSDavid du Colombier 	int a1, a2, a3, a4, r;
3237dd7cddfSDavid du Colombier 	char *c1, *c3, *c4;
3247dd7cddfSDavid du Colombier 	Optab *o, *e;
3257dd7cddfSDavid du Colombier 
3267dd7cddfSDavid du Colombier 	a1 = p->optab;
3277dd7cddfSDavid du Colombier 	if(a1)
3287dd7cddfSDavid du Colombier 		return optab+(a1-1);
3297dd7cddfSDavid du Colombier 	a1 = p->from.class;
3307dd7cddfSDavid du Colombier 	if(a1 == 0) {
3317dd7cddfSDavid du Colombier 		a1 = aclass(&p->from) + 1;
3327dd7cddfSDavid du Colombier 		p->from.class = a1;
3337dd7cddfSDavid du Colombier 	}
3347dd7cddfSDavid du Colombier 	a1--;
3357dd7cddfSDavid du Colombier 	a3 = p->from3.class;
3367dd7cddfSDavid du Colombier 	if(a3 == 0) {
3377dd7cddfSDavid du Colombier 		a3 = aclass(&p->from3) + 1;
3387dd7cddfSDavid du Colombier 		p->from3.class = a3;
3397dd7cddfSDavid du Colombier 	}
3407dd7cddfSDavid du Colombier 	a3--;
3417dd7cddfSDavid du Colombier 	a4 = p->to.class;
3427dd7cddfSDavid du Colombier 	if(a4 == 0) {
3437dd7cddfSDavid du Colombier 		a4 = aclass(&p->to) + 1;
3447dd7cddfSDavid du Colombier 		p->to.class = a4;
3457dd7cddfSDavid du Colombier 	}
3467dd7cddfSDavid du Colombier 	a4--;
3477dd7cddfSDavid du Colombier 	a2 = C_NONE;
3487dd7cddfSDavid du Colombier 	if(p->reg != NREG)
3497dd7cddfSDavid du Colombier 		a2 = C_REG;
3507dd7cddfSDavid du Colombier 	r = p->as;
3517dd7cddfSDavid du Colombier 	o = oprange[r].start;
3527dd7cddfSDavid du Colombier 	if(o == 0)
3537dd7cddfSDavid du Colombier 		o = oprange[r].stop; /* just generate an error */
3547dd7cddfSDavid du Colombier 	e = oprange[r].stop;
3557dd7cddfSDavid du Colombier 	c1 = xcmp[a1];
3567dd7cddfSDavid du Colombier 	c3 = xcmp[a3];
3577dd7cddfSDavid du Colombier 	c4 = xcmp[a4];
3587dd7cddfSDavid du Colombier 	for(; o<e; o++)
3597dd7cddfSDavid du Colombier 		if(o->a2 == a2)
3607dd7cddfSDavid du Colombier 		if(c1[o->a1])
3617dd7cddfSDavid du Colombier 		if(c3[o->a3])
3627dd7cddfSDavid du Colombier 		if(c4[o->a4]) {
3637dd7cddfSDavid du Colombier 			p->optab = (o-optab)+1;
3647dd7cddfSDavid du Colombier 			return o;
3657dd7cddfSDavid du Colombier 		}
3666b6b9ac8SDavid du Colombier 	diag("illegal combination %A %R %R %R %R",
3677dd7cddfSDavid du Colombier 		p->as, a1, a2, a3, a4);
3687dd7cddfSDavid du Colombier 	if(1||!debug['a'])
3697dd7cddfSDavid du Colombier 		prasm(p);
3707dd7cddfSDavid du Colombier 	if(o == 0)
3717dd7cddfSDavid du Colombier 		errorexit();
3727dd7cddfSDavid du Colombier 	return o;
3737dd7cddfSDavid du Colombier }
3747dd7cddfSDavid du Colombier 
3757dd7cddfSDavid du Colombier int
cmp(int a,int b)3767dd7cddfSDavid du Colombier cmp(int a, int b)
3777dd7cddfSDavid du Colombier {
3787dd7cddfSDavid du Colombier 
3797dd7cddfSDavid du Colombier 	if(a == b)
3807dd7cddfSDavid du Colombier 		return 1;
3817dd7cddfSDavid du Colombier 	switch(a) {
3827dd7cddfSDavid du Colombier 	case C_LCON:
3837dd7cddfSDavid du Colombier 		if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
3847dd7cddfSDavid du Colombier 			return 1;
3857dd7cddfSDavid du Colombier 		break;
3867dd7cddfSDavid du Colombier 	case C_ADDCON:
3877dd7cddfSDavid du Colombier 		if(b == C_ZCON || b == C_SCON)
3887dd7cddfSDavid du Colombier 			return 1;
3897dd7cddfSDavid du Colombier 		break;
3907dd7cddfSDavid du Colombier 	case C_ANDCON:
3917dd7cddfSDavid du Colombier 		if(b == C_ZCON || b == C_SCON)
3927dd7cddfSDavid du Colombier 			return 1;
3937dd7cddfSDavid du Colombier 		break;
3947dd7cddfSDavid du Colombier 	case C_SPR:
3957dd7cddfSDavid du Colombier 		if(b == C_LR || b == C_XER || b == C_CTR)
3967dd7cddfSDavid du Colombier 			return 1;
3977dd7cddfSDavid du Colombier 		break;
3987dd7cddfSDavid du Colombier 	case C_UCON:
3997dd7cddfSDavid du Colombier 		if(b == C_ZCON)
4007dd7cddfSDavid du Colombier 			return 1;
4017dd7cddfSDavid du Colombier 		break;
4027dd7cddfSDavid du Colombier 	case C_SCON:
4037dd7cddfSDavid du Colombier 		if(b == C_ZCON)
4047dd7cddfSDavid du Colombier 			return 1;
4057dd7cddfSDavid du Colombier 		break;
4067dd7cddfSDavid du Colombier 	case C_LACON:
4077dd7cddfSDavid du Colombier 		if(b == C_SACON)
4087dd7cddfSDavid du Colombier 			return 1;
4097dd7cddfSDavid du Colombier 		break;
4107dd7cddfSDavid du Colombier 	case C_LBRA:
4117dd7cddfSDavid du Colombier 		if(b == C_SBRA)
4127dd7cddfSDavid du Colombier 			return 1;
4137dd7cddfSDavid du Colombier 		break;
4147dd7cddfSDavid du Colombier 	case C_LEXT:
4157dd7cddfSDavid du Colombier 		if(b == C_SEXT)
4167dd7cddfSDavid du Colombier 			return 1;
4177dd7cddfSDavid du Colombier 		break;
4187dd7cddfSDavid du Colombier 	case C_LAUTO:
4197dd7cddfSDavid du Colombier 		if(b == C_SAUTO)
4207dd7cddfSDavid du Colombier 			return 1;
4217dd7cddfSDavid du Colombier 		break;
4227dd7cddfSDavid du Colombier 	case C_REG:
423375daca8SDavid du Colombier 		if(r0iszero && b == C_ZCON)
4247dd7cddfSDavid du Colombier 			return 1;
4257dd7cddfSDavid du Colombier 		break;
4267dd7cddfSDavid du Colombier 	case C_LOREG:
4277dd7cddfSDavid du Colombier 		if(b == C_ZOREG || b == C_SOREG)
4287dd7cddfSDavid du Colombier 			return 1;
4297dd7cddfSDavid du Colombier 		break;
4307dd7cddfSDavid du Colombier 	case C_SOREG:
4317dd7cddfSDavid du Colombier 		if(b == C_ZOREG)
4327dd7cddfSDavid du Colombier 			return 1;
4337dd7cddfSDavid du Colombier 		break;
4347dd7cddfSDavid du Colombier 
4357dd7cddfSDavid du Colombier 	case C_ANY:
4367dd7cddfSDavid du Colombier 		return 1;
4377dd7cddfSDavid du Colombier 	}
4387dd7cddfSDavid du Colombier 	return 0;
4397dd7cddfSDavid du Colombier }
4407dd7cddfSDavid du Colombier 
4417dd7cddfSDavid du Colombier int
ocmp(void * a1,void * a2)4427dd7cddfSDavid du Colombier ocmp(void *a1, void *a2)
4437dd7cddfSDavid du Colombier {
4447dd7cddfSDavid du Colombier 	Optab *p1, *p2;
4457dd7cddfSDavid du Colombier 	int n;
4467dd7cddfSDavid du Colombier 
4477dd7cddfSDavid du Colombier 	p1 = a1;
4487dd7cddfSDavid du Colombier 	p2 = a2;
4497dd7cddfSDavid du Colombier 	n = p1->as - p2->as;
4507dd7cddfSDavid du Colombier 	if(n)
4517dd7cddfSDavid du Colombier 		return n;
4527dd7cddfSDavid du Colombier 	n = p1->a1 - p2->a1;
4537dd7cddfSDavid du Colombier 	if(n)
4547dd7cddfSDavid du Colombier 		return n;
4557dd7cddfSDavid du Colombier 	n = p1->a2 - p2->a2;
4567dd7cddfSDavid du Colombier 	if(n)
4577dd7cddfSDavid du Colombier 		return n;
4587dd7cddfSDavid du Colombier 	n = p1->a3 - p2->a3;
4597dd7cddfSDavid du Colombier 	if(n)
4607dd7cddfSDavid du Colombier 		return n;
4617dd7cddfSDavid du Colombier 	n = p1->a4 - p2->a4;
4627dd7cddfSDavid du Colombier 	if(n)
4637dd7cddfSDavid du Colombier 		return n;
4647dd7cddfSDavid du Colombier 	return 0;
4657dd7cddfSDavid du Colombier }
4667dd7cddfSDavid du Colombier 
4677dd7cddfSDavid du Colombier void
buildop(void)4687dd7cddfSDavid du Colombier buildop(void)
4697dd7cddfSDavid du Colombier {
4707dd7cddfSDavid du Colombier 	int i, n, r;
4717dd7cddfSDavid du Colombier 
4727dd7cddfSDavid du Colombier 	for(i=0; i<C_NCLASS; i++)
4737dd7cddfSDavid du Colombier 		for(n=0; n<C_NCLASS; n++)
4747dd7cddfSDavid du Colombier 			xcmp[i][n] = cmp(n, i);
4757dd7cddfSDavid du Colombier 	for(n=0; optab[n].as != AXXX; n++)
4767dd7cddfSDavid du Colombier 		;
4777dd7cddfSDavid du Colombier 	qsort(optab, n, sizeof(optab[0]), ocmp);
4787dd7cddfSDavid du Colombier 	for(i=0; i<n; i++) {
4797dd7cddfSDavid du Colombier 		r = optab[i].as;
4807dd7cddfSDavid du Colombier 		oprange[r].start = optab+i;
4817dd7cddfSDavid du Colombier 		while(optab[i].as == r)
4827dd7cddfSDavid du Colombier 			i++;
4837dd7cddfSDavid du Colombier 		oprange[r].stop = optab+i;
4847dd7cddfSDavid du Colombier 		i--;
4857dd7cddfSDavid du Colombier 
4867dd7cddfSDavid du Colombier 		switch(r)
4877dd7cddfSDavid du Colombier 		{
4887dd7cddfSDavid du Colombier 		default:
4896b6b9ac8SDavid du Colombier 			diag("unknown op in build: %A", r);
4907dd7cddfSDavid du Colombier 			errorexit();
4917dd7cddfSDavid du Colombier 		case ADCBF:	/* unary indexed: op (b+a); op (b) */
4927dd7cddfSDavid du Colombier 			oprange[ADCBI] = oprange[r];
4937dd7cddfSDavid du Colombier 			oprange[ADCBST] = oprange[r];
4947dd7cddfSDavid du Colombier 			oprange[ADCBT] = oprange[r];
4957dd7cddfSDavid du Colombier 			oprange[ADCBTST] = oprange[r];
4967dd7cddfSDavid du Colombier 			oprange[ADCBZ] = oprange[r];
4977dd7cddfSDavid du Colombier 			oprange[AICBI] = oprange[r];
4987dd7cddfSDavid du Colombier 			break;
4997dd7cddfSDavid du Colombier 		case AECOWX:	/* indexed store: op s,(b+a); op s,(b) */
5007dd7cddfSDavid du Colombier 			oprange[ASTWCCC] = oprange[r];
5017dd7cddfSDavid du Colombier 			break;
5027dd7cddfSDavid du Colombier 		case AREM:	/* macro */
5037dd7cddfSDavid du Colombier 			oprange[AREMCC] = oprange[r];
5047dd7cddfSDavid du Colombier 			oprange[AREMV] = oprange[r];
5057dd7cddfSDavid du Colombier 			oprange[AREMVCC] = oprange[r];
5067dd7cddfSDavid du Colombier 			oprange[AREMU] = oprange[r];
5077dd7cddfSDavid du Colombier 			oprange[AREMUCC] = oprange[r];
5087dd7cddfSDavid du Colombier 			oprange[AREMUV] = oprange[r];
5097dd7cddfSDavid du Colombier 			oprange[AREMUVCC] = oprange[r];
5107dd7cddfSDavid du Colombier 			break;
5117dd7cddfSDavid du Colombier 		case ADIVW:	/* op Rb[,Ra],Rd */
5127dd7cddfSDavid du Colombier 			oprange[AMULHW] = oprange[r];
5137dd7cddfSDavid du Colombier 			oprange[AMULHWCC] = oprange[r];
5147dd7cddfSDavid du Colombier 			oprange[AMULHWU] = oprange[r];
5157dd7cddfSDavid du Colombier 			oprange[AMULHWUCC] = oprange[r];
5167dd7cddfSDavid du Colombier 			oprange[AMULLWCC] = oprange[r];
5177dd7cddfSDavid du Colombier 			oprange[AMULLWVCC] = oprange[r];
5187dd7cddfSDavid du Colombier 			oprange[AMULLWV] = oprange[r];
5197dd7cddfSDavid du Colombier 			oprange[ADIVWCC] = oprange[r];
5207dd7cddfSDavid du Colombier 			oprange[ADIVWV] = oprange[r];
5217dd7cddfSDavid du Colombier 			oprange[ADIVWVCC] = oprange[r];
5227dd7cddfSDavid du Colombier 			oprange[ADIVWU] = oprange[r];
5237dd7cddfSDavid du Colombier 			oprange[ADIVWUCC] = oprange[r];
5247dd7cddfSDavid du Colombier 			oprange[ADIVWUV] = oprange[r];
5257dd7cddfSDavid du Colombier 			oprange[ADIVWUVCC] = oprange[r];
5267dd7cddfSDavid du Colombier 			oprange[AADDCC] = oprange[r];
5277dd7cddfSDavid du Colombier 			oprange[AADDCV] = oprange[r];
5287dd7cddfSDavid du Colombier 			oprange[AADDCVCC] = oprange[r];
5297dd7cddfSDavid du Colombier 			oprange[AADDV] = oprange[r];
5307dd7cddfSDavid du Colombier 			oprange[AADDVCC] = oprange[r];
5317dd7cddfSDavid du Colombier 			oprange[AADDE] = oprange[r];
5327dd7cddfSDavid du Colombier 			oprange[AADDECC] = oprange[r];
5337dd7cddfSDavid du Colombier 			oprange[AADDEV] = oprange[r];
5347dd7cddfSDavid du Colombier 			oprange[AADDEVCC] = oprange[r];
5357dd7cddfSDavid du Colombier 			oprange[ACRAND] = oprange[r];
5367dd7cddfSDavid du Colombier 			oprange[ACRANDN] = oprange[r];
5377dd7cddfSDavid du Colombier 			oprange[ACREQV] = oprange[r];
5387dd7cddfSDavid du Colombier 			oprange[ACRNAND] = oprange[r];
5397dd7cddfSDavid du Colombier 			oprange[ACRNOR] = oprange[r];
5407dd7cddfSDavid du Colombier 			oprange[ACROR] = oprange[r];
5417dd7cddfSDavid du Colombier 			oprange[ACRORN] = oprange[r];
5427dd7cddfSDavid du Colombier 			oprange[ACRXOR] = oprange[r];
543375daca8SDavid du Colombier 			oprange[AMULCHW] = oprange[r];
544375daca8SDavid du Colombier 			oprange[AMULCHWCC] = oprange[r];
545375daca8SDavid du Colombier 			oprange[AMULCHWU] = oprange[r];
546375daca8SDavid du Colombier 			oprange[AMULCHWUCC] = oprange[r];
547375daca8SDavid du Colombier 			oprange[AMULHHW] = oprange[r];
548375daca8SDavid du Colombier 			oprange[AMULHHWCC] = oprange[r];
549375daca8SDavid du Colombier 			oprange[AMULHHWU] = oprange[r];
550375daca8SDavid du Colombier 			oprange[AMULHHWUCC] = oprange[r];
551375daca8SDavid du Colombier 			oprange[AMULLHW] = oprange[r];
552375daca8SDavid du Colombier 			oprange[AMULLHWCC] = oprange[r];
553375daca8SDavid du Colombier 			oprange[AMULLHWU] = oprange[r];
554375daca8SDavid du Colombier 			oprange[AMULLHWUCC] = oprange[r];
555375daca8SDavid du Colombier 			break;
556375daca8SDavid du Colombier 		case AMACCHW:	/* strictly 3 registers */
557375daca8SDavid du Colombier 			oprange[AMACCHWCC] = oprange[r];
558375daca8SDavid du Colombier 			oprange[AMACCHWS] = oprange[r];
559375daca8SDavid du Colombier 			oprange[AMACCHWSCC] = oprange[r];
560375daca8SDavid du Colombier 			oprange[AMACCHWSU] = oprange[r];
561375daca8SDavid du Colombier 			oprange[AMACCHWSUCC] = oprange[r];
562375daca8SDavid du Colombier 			oprange[AMACCHWSUV] = oprange[r];
563375daca8SDavid du Colombier 			oprange[AMACCHWSUVCC] = oprange[r];
564375daca8SDavid du Colombier 			oprange[AMACCHWSV] = oprange[r];
565375daca8SDavid du Colombier 			oprange[AMACCHWSVCC] = oprange[r];
566375daca8SDavid du Colombier 			oprange[AMACCHWU] = oprange[r];
567375daca8SDavid du Colombier 			oprange[AMACCHWUCC] = oprange[r];
568375daca8SDavid du Colombier 			oprange[AMACCHWUV] = oprange[r];
569375daca8SDavid du Colombier 			oprange[AMACCHWUVCC] = oprange[r];
570375daca8SDavid du Colombier 			oprange[AMACCHWV] = oprange[r];
571375daca8SDavid du Colombier 			oprange[AMACCHWVCC] = oprange[r];
572375daca8SDavid du Colombier 			oprange[AMACHHW] = oprange[r];
573375daca8SDavid du Colombier 			oprange[AMACHHWCC] = oprange[r];
574375daca8SDavid du Colombier 			oprange[AMACHHWS] = oprange[r];
575375daca8SDavid du Colombier 			oprange[AMACHHWSCC] = oprange[r];
576375daca8SDavid du Colombier 			oprange[AMACHHWSU] = oprange[r];
577375daca8SDavid du Colombier 			oprange[AMACHHWSUCC] = oprange[r];
578375daca8SDavid du Colombier 			oprange[AMACHHWSUV] = oprange[r];
579375daca8SDavid du Colombier 			oprange[AMACHHWSUVCC] = oprange[r];
580375daca8SDavid du Colombier 			oprange[AMACHHWSV] = oprange[r];
581375daca8SDavid du Colombier 			oprange[AMACHHWSVCC] = oprange[r];
582375daca8SDavid du Colombier 			oprange[AMACHHWU] = oprange[r];
583375daca8SDavid du Colombier 			oprange[AMACHHWUCC] = oprange[r];
584375daca8SDavid du Colombier 			oprange[AMACHHWUV] = oprange[r];
585375daca8SDavid du Colombier 			oprange[AMACHHWUVCC] = oprange[r];
586375daca8SDavid du Colombier 			oprange[AMACHHWV] = oprange[r];
587375daca8SDavid du Colombier 			oprange[AMACHHWVCC] = oprange[r];
588375daca8SDavid du Colombier 			oprange[AMACLHW] = oprange[r];
589375daca8SDavid du Colombier 			oprange[AMACLHWCC] = oprange[r];
590375daca8SDavid du Colombier 			oprange[AMACLHWS] = oprange[r];
591375daca8SDavid du Colombier 			oprange[AMACLHWSCC] = oprange[r];
592375daca8SDavid du Colombier 			oprange[AMACLHWSU] = oprange[r];
593375daca8SDavid du Colombier 			oprange[AMACLHWSUCC] = oprange[r];
594375daca8SDavid du Colombier 			oprange[AMACLHWSUV] = oprange[r];
595375daca8SDavid du Colombier 			oprange[AMACLHWSUVCC] = oprange[r];
596375daca8SDavid du Colombier 			oprange[AMACLHWSV] = oprange[r];
597375daca8SDavid du Colombier 			oprange[AMACLHWSVCC] = oprange[r];
598375daca8SDavid du Colombier 			oprange[AMACLHWU] = oprange[r];
599375daca8SDavid du Colombier 			oprange[AMACLHWUCC] = oprange[r];
600375daca8SDavid du Colombier 			oprange[AMACLHWUV] = oprange[r];
601375daca8SDavid du Colombier 			oprange[AMACLHWUVCC] = oprange[r];
602375daca8SDavid du Colombier 			oprange[AMACLHWV] = oprange[r];
603375daca8SDavid du Colombier 			oprange[AMACLHWVCC] = oprange[r];
604375daca8SDavid du Colombier 			oprange[ANMACCHW] = oprange[r];
605375daca8SDavid du Colombier 			oprange[ANMACCHWCC] = oprange[r];
606375daca8SDavid du Colombier 			oprange[ANMACCHWS] = oprange[r];
607375daca8SDavid du Colombier 			oprange[ANMACCHWSCC] = oprange[r];
608375daca8SDavid du Colombier 			oprange[ANMACCHWSV] = oprange[r];
609375daca8SDavid du Colombier 			oprange[ANMACCHWSVCC] = oprange[r];
610375daca8SDavid du Colombier 			oprange[ANMACCHWV] = oprange[r];
611375daca8SDavid du Colombier 			oprange[ANMACCHWVCC] = oprange[r];
612375daca8SDavid du Colombier 			oprange[ANMACHHW] = oprange[r];
613375daca8SDavid du Colombier 			oprange[ANMACHHWCC] = oprange[r];
614375daca8SDavid du Colombier 			oprange[ANMACHHWS] = oprange[r];
615375daca8SDavid du Colombier 			oprange[ANMACHHWSCC] = oprange[r];
616375daca8SDavid du Colombier 			oprange[ANMACHHWSV] = oprange[r];
617375daca8SDavid du Colombier 			oprange[ANMACHHWSVCC] = oprange[r];
618375daca8SDavid du Colombier 			oprange[ANMACHHWV] = oprange[r];
619375daca8SDavid du Colombier 			oprange[ANMACHHWVCC] = oprange[r];
620375daca8SDavid du Colombier 			oprange[ANMACLHW] = oprange[r];
621375daca8SDavid du Colombier 			oprange[ANMACLHWCC] = oprange[r];
622375daca8SDavid du Colombier 			oprange[ANMACLHWS] = oprange[r];
623375daca8SDavid du Colombier 			oprange[ANMACLHWSCC] = oprange[r];
624375daca8SDavid du Colombier 			oprange[ANMACLHWSV] = oprange[r];
625375daca8SDavid du Colombier 			oprange[ANMACLHWSVCC] = oprange[r];
626375daca8SDavid du Colombier 			oprange[ANMACLHWV] = oprange[r];
627375daca8SDavid du Colombier 			oprange[ANMACLHWVCC] = oprange[r];
6287dd7cddfSDavid du Colombier 			break;
6297dd7cddfSDavid du Colombier 		case AMOVBZ:	/* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
6307dd7cddfSDavid du Colombier 			oprange[AMOVH] = oprange[r];
6317dd7cddfSDavid du Colombier 			oprange[AMOVHZ] = oprange[r];
6327dd7cddfSDavid du Colombier 			break;
6337dd7cddfSDavid du Colombier 		case AMOVBZU:	/* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */
6347dd7cddfSDavid du Colombier 			oprange[AMOVHU] = oprange[r];
6357dd7cddfSDavid du Colombier 			oprange[AMOVHZU] = oprange[r];
6367dd7cddfSDavid du Colombier 			oprange[AMOVWU] = oprange[r];
6377dd7cddfSDavid du Colombier 			oprange[AMOVMW] = oprange[r];
6387dd7cddfSDavid du Colombier 			break;
6397dd7cddfSDavid du Colombier 		case AAND:	/* logical op Rb,Rs,Ra; no literal */
6407dd7cddfSDavid du Colombier 			oprange[AANDN] = oprange[r];
6417dd7cddfSDavid du Colombier 			oprange[AANDNCC] = oprange[r];
6427dd7cddfSDavid du Colombier 			oprange[AEQV] = oprange[r];
6437dd7cddfSDavid du Colombier 			oprange[AEQVCC] = oprange[r];
6447dd7cddfSDavid du Colombier 			oprange[ANAND] = oprange[r];
6457dd7cddfSDavid du Colombier 			oprange[ANANDCC] = oprange[r];
6467dd7cddfSDavid du Colombier 			oprange[ANOR] = oprange[r];
6477dd7cddfSDavid du Colombier 			oprange[ANORCC] = oprange[r];
6487dd7cddfSDavid du Colombier 			oprange[AORCC] = oprange[r];
6497dd7cddfSDavid du Colombier 			oprange[AORN] = oprange[r];
6507dd7cddfSDavid du Colombier 			oprange[AORNCC] = oprange[r];
6517dd7cddfSDavid du Colombier 			oprange[AXORCC] = oprange[r];
6527dd7cddfSDavid du Colombier 			break;
6537dd7cddfSDavid du Colombier 		case AADDME:	/* op Ra, Rd */
6547dd7cddfSDavid du Colombier 			oprange[AADDMECC] = oprange[r];
6557dd7cddfSDavid du Colombier 			oprange[AADDMEV] = oprange[r];
6567dd7cddfSDavid du Colombier 			oprange[AADDMEVCC] = oprange[r];
6577dd7cddfSDavid du Colombier 			oprange[AADDZE] = oprange[r];
6587dd7cddfSDavid du Colombier 			oprange[AADDZECC] = oprange[r];
6597dd7cddfSDavid du Colombier 			oprange[AADDZEV] = oprange[r];
6607dd7cddfSDavid du Colombier 			oprange[AADDZEVCC] = oprange[r];
6617dd7cddfSDavid du Colombier 			oprange[ASUBME] = oprange[r];
6627dd7cddfSDavid du Colombier 			oprange[ASUBMECC] = oprange[r];
6637dd7cddfSDavid du Colombier 			oprange[ASUBMEV] = oprange[r];
6647dd7cddfSDavid du Colombier 			oprange[ASUBMEVCC] = oprange[r];
6657dd7cddfSDavid du Colombier 			oprange[ASUBZE] = oprange[r];
6667dd7cddfSDavid du Colombier 			oprange[ASUBZECC] = oprange[r];
6677dd7cddfSDavid du Colombier 			oprange[ASUBZEV] = oprange[r];
6687dd7cddfSDavid du Colombier 			oprange[ASUBZEVCC] = oprange[r];
6697dd7cddfSDavid du Colombier 			break;
6707dd7cddfSDavid du Colombier 		case AADDC:
6717dd7cddfSDavid du Colombier 			oprange[AADDCCC] = oprange[r];
6727dd7cddfSDavid du Colombier 			break;
6737dd7cddfSDavid du Colombier 		case ABEQ:
6747dd7cddfSDavid du Colombier 			oprange[ABGE] = oprange[r];
6757dd7cddfSDavid du Colombier 			oprange[ABGT] = oprange[r];
6767dd7cddfSDavid du Colombier 			oprange[ABLE] = oprange[r];
6777dd7cddfSDavid du Colombier 			oprange[ABLT] = oprange[r];
6787dd7cddfSDavid du Colombier 			oprange[ABNE] = oprange[r];
6797dd7cddfSDavid du Colombier 			oprange[ABVC] = oprange[r];
6807dd7cddfSDavid du Colombier 			oprange[ABVS] = oprange[r];
6817dd7cddfSDavid du Colombier 			break;
6827dd7cddfSDavid du Colombier 		case ABR:
6837dd7cddfSDavid du Colombier 			oprange[ABL] = oprange[r];
6847dd7cddfSDavid du Colombier 			break;
6857dd7cddfSDavid du Colombier 		case ABC:
6867dd7cddfSDavid du Colombier 			oprange[ABCL] = oprange[r];
6877dd7cddfSDavid du Colombier 			break;
6887dd7cddfSDavid du Colombier 		case AEXTSB:	/* op Rs, Ra */
6897dd7cddfSDavid du Colombier 			oprange[AEXTSBCC] = oprange[r];
6907dd7cddfSDavid du Colombier 			oprange[AEXTSH] = oprange[r];
6917dd7cddfSDavid du Colombier 			oprange[AEXTSHCC] = oprange[r];
6927dd7cddfSDavid du Colombier 			oprange[ACNTLZW] = oprange[r];
6937dd7cddfSDavid du Colombier 			oprange[ACNTLZWCC] = oprange[r];
6947dd7cddfSDavid du Colombier 			break;
6957dd7cddfSDavid du Colombier 		case AFABS:	/* fop [s,]d */
6967dd7cddfSDavid du Colombier 			oprange[AFABSCC] = oprange[r];
6977dd7cddfSDavid du Colombier 			oprange[AFNABS] = oprange[r];
6987dd7cddfSDavid du Colombier 			oprange[AFNABSCC] = oprange[r];
6997dd7cddfSDavid du Colombier 			oprange[AFNEG] = oprange[r];
7007dd7cddfSDavid du Colombier 			oprange[AFNEGCC] = oprange[r];
7017dd7cddfSDavid du Colombier 			oprange[AFRSP] = oprange[r];
7027dd7cddfSDavid du Colombier 			oprange[AFRSPCC] = oprange[r];
7037dd7cddfSDavid du Colombier 			oprange[AFCTIW] = oprange[r];
7047dd7cddfSDavid du Colombier 			oprange[AFCTIWCC] = oprange[r];
7057dd7cddfSDavid du Colombier 			oprange[AFCTIWZ] = oprange[r];
7067dd7cddfSDavid du Colombier 			oprange[AFCTIWZCC] = oprange[r];
707*6891d857SDavid du Colombier 			oprange[AFRES] = oprange[r];
708*6891d857SDavid du Colombier 			oprange[AFRESCC] = oprange[r];
709*6891d857SDavid du Colombier 			oprange[AFRSQRTE] = oprange[r];
710*6891d857SDavid du Colombier 			oprange[AFRSQRTECC] = oprange[r];
711*6891d857SDavid du Colombier 			oprange[AFSQRT] = oprange[r];
712*6891d857SDavid du Colombier 			oprange[AFSQRTCC] = oprange[r];
713*6891d857SDavid du Colombier 			oprange[AFSQRTS] = oprange[r];
714*6891d857SDavid du Colombier 			oprange[AFSQRTSCC] = oprange[r];
715*6891d857SDavid du Colombier 			oprange[AFPRE] = oprange[r];
716*6891d857SDavid du Colombier 			oprange[AFPRSQRTE] = oprange[r];
717*6891d857SDavid du Colombier 			oprange[AFPABS] = oprange[r];
718*6891d857SDavid du Colombier 			oprange[AFPNEG] = oprange[r];
719*6891d857SDavid du Colombier 			oprange[AFPRSP] = oprange[r];
720*6891d857SDavid du Colombier 			oprange[AFPNABS] = oprange[r];
721*6891d857SDavid du Colombier 			oprange[AFSABS] = oprange[r];
722*6891d857SDavid du Colombier 			oprange[AFSNEG] = oprange[r];
723*6891d857SDavid du Colombier 			oprange[AFSNABS] = oprange[r];
724*6891d857SDavid du Colombier 			oprange[AFPCTIW] = oprange[r];
725*6891d857SDavid du Colombier 			oprange[AFPCTIWZ] = oprange[r];
7267dd7cddfSDavid du Colombier 			break;
7277dd7cddfSDavid du Colombier 		case AFADD:
7287dd7cddfSDavid du Colombier 			oprange[AFADDS] = oprange[r];
7297dd7cddfSDavid du Colombier 			oprange[AFADDCC] = oprange[r];
7307dd7cddfSDavid du Colombier 			oprange[AFADDSCC] = oprange[r];
7317dd7cddfSDavid du Colombier 			oprange[AFDIV] = oprange[r];
7327dd7cddfSDavid du Colombier 			oprange[AFDIVS] = oprange[r];
7337dd7cddfSDavid du Colombier 			oprange[AFDIVCC] = oprange[r];
7347dd7cddfSDavid du Colombier 			oprange[AFDIVSCC] = oprange[r];
7357dd7cddfSDavid du Colombier 			oprange[AFSUB] = oprange[r];
7367dd7cddfSDavid du Colombier 			oprange[AFSUBS] = oprange[r];
7377dd7cddfSDavid du Colombier 			oprange[AFSUBCC] = oprange[r];
7387dd7cddfSDavid du Colombier 			oprange[AFSUBSCC] = oprange[r];
739*6891d857SDavid du Colombier 			oprange[AFPADD] = oprange[r];
740*6891d857SDavid du Colombier 			oprange[AFPSUB] = oprange[r];
7417dd7cddfSDavid du Colombier 			break;
7427dd7cddfSDavid du Colombier 		case AFMADD:
7437dd7cddfSDavid du Colombier 			oprange[AFMADDCC] = oprange[r];
7447dd7cddfSDavid du Colombier 			oprange[AFMADDS] = oprange[r];
7457dd7cddfSDavid du Colombier 			oprange[AFMADDSCC] = oprange[r];
7467dd7cddfSDavid du Colombier 			oprange[AFMSUB] = oprange[r];
7477dd7cddfSDavid du Colombier 			oprange[AFMSUBCC] = oprange[r];
7487dd7cddfSDavid du Colombier 			oprange[AFMSUBS] = oprange[r];
7497dd7cddfSDavid du Colombier 			oprange[AFMSUBSCC] = oprange[r];
7507dd7cddfSDavid du Colombier 			oprange[AFNMADD] = oprange[r];
7517dd7cddfSDavid du Colombier 			oprange[AFNMADDCC] = oprange[r];
7527dd7cddfSDavid du Colombier 			oprange[AFNMADDS] = oprange[r];
7537dd7cddfSDavid du Colombier 			oprange[AFNMADDSCC] = oprange[r];
7547dd7cddfSDavid du Colombier 			oprange[AFNMSUB] = oprange[r];
7557dd7cddfSDavid du Colombier 			oprange[AFNMSUBCC] = oprange[r];
7567dd7cddfSDavid du Colombier 			oprange[AFNMSUBS] = oprange[r];
7577dd7cddfSDavid du Colombier 			oprange[AFNMSUBSCC] = oprange[r];
758*6891d857SDavid du Colombier 			oprange[AFSEL] = oprange[r];
759*6891d857SDavid du Colombier 			oprange[AFSELCC] = oprange[r];
760*6891d857SDavid du Colombier 			oprange[AFPSEL] = oprange[r];
761*6891d857SDavid du Colombier 			oprange[AFPMADD] = oprange[r];
762*6891d857SDavid du Colombier 			oprange[AFXMADD] = oprange[r];
763*6891d857SDavid du Colombier 			oprange[AFXCPMADD] = oprange[r];
764*6891d857SDavid du Colombier 			oprange[AFXCSMADD] = oprange[r];
765*6891d857SDavid du Colombier 			oprange[AFPNMADD] = oprange[r];
766*6891d857SDavid du Colombier 			oprange[AFXNMADD] = oprange[r];
767*6891d857SDavid du Colombier 			oprange[AFXCPNMADD] = oprange[r];
768*6891d857SDavid du Colombier 			oprange[AFXCSNMADD] = oprange[r];
769*6891d857SDavid du Colombier 			oprange[AFPMSUB] = oprange[r];
770*6891d857SDavid du Colombier 			oprange[AFXMSUB] = oprange[r];
771*6891d857SDavid du Colombier 			oprange[AFXCPMSUB] = oprange[r];
772*6891d857SDavid du Colombier 			oprange[AFXCSMSUB] = oprange[r];
773*6891d857SDavid du Colombier 			oprange[AFPNMSUB] = oprange[r];
774*6891d857SDavid du Colombier 			oprange[AFXNMSUB] = oprange[r];
775*6891d857SDavid du Colombier 			oprange[AFXCPNMSUB] = oprange[r];
776*6891d857SDavid du Colombier 			oprange[AFXCSNMSUB] = oprange[r];
777*6891d857SDavid du Colombier 			oprange[AFXCPNPMA] = oprange[r];
778*6891d857SDavid du Colombier 			oprange[AFXCSNPMA] = oprange[r];
779*6891d857SDavid du Colombier 			oprange[AFXCPNSMA] = oprange[r];
780*6891d857SDavid du Colombier 			oprange[AFXCSNSMA] = oprange[r];
781*6891d857SDavid du Colombier 			oprange[AFXCXNPMA] = oprange[r];
782*6891d857SDavid du Colombier 			oprange[AFXCXNSMA] = oprange[r];
783*6891d857SDavid du Colombier 			oprange[AFXCXMA] = oprange[r];
784*6891d857SDavid du Colombier 			oprange[AFXCXNMS] = oprange[r];
7857dd7cddfSDavid du Colombier 			break;
7867dd7cddfSDavid du Colombier 		case AFMUL:
7877dd7cddfSDavid du Colombier 			oprange[AFMULS] = oprange[r];
7887dd7cddfSDavid du Colombier 			oprange[AFMULCC] = oprange[r];
7897dd7cddfSDavid du Colombier 			oprange[AFMULSCC] = oprange[r];
790*6891d857SDavid du Colombier 			oprange[AFPMUL] = oprange[r];
791*6891d857SDavid du Colombier 			oprange[AFXMUL] = oprange[r];
792*6891d857SDavid du Colombier 			oprange[AFXPMUL] = oprange[r];
793*6891d857SDavid du Colombier 			oprange[AFXSMUL] = oprange[r];
7947dd7cddfSDavid du Colombier 			break;
7957dd7cddfSDavid du Colombier 		case AFCMPO:
7967dd7cddfSDavid du Colombier 			oprange[AFCMPU] = oprange[r];
7977dd7cddfSDavid du Colombier 			break;
7987dd7cddfSDavid du Colombier 		case AMTFSB0:
7997dd7cddfSDavid du Colombier 			oprange[AMTFSB0CC] = oprange[r];
8007dd7cddfSDavid du Colombier 			oprange[AMTFSB1] = oprange[r];
8017dd7cddfSDavid du Colombier 			oprange[AMTFSB1CC] = oprange[r];
8027dd7cddfSDavid du Colombier 			break;
8037dd7cddfSDavid du Colombier 		case ANEG:	/* op [Ra,] Rd */
8047dd7cddfSDavid du Colombier 			oprange[ANEGCC] = oprange[r];
8057dd7cddfSDavid du Colombier 			oprange[ANEGV] = oprange[r];
8067dd7cddfSDavid du Colombier 			oprange[ANEGVCC] = oprange[r];
8077dd7cddfSDavid du Colombier 			break;
8087dd7cddfSDavid du Colombier 		case AOR:	/* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
8097dd7cddfSDavid du Colombier 			oprange[AXOR] = oprange[r];
8107dd7cddfSDavid du Colombier 			break;
8117dd7cddfSDavid du Colombier 		case ASLW:
8127dd7cddfSDavid du Colombier 			oprange[ASLWCC] = oprange[r];
8137dd7cddfSDavid du Colombier 			oprange[ASRW] = oprange[r];
8147dd7cddfSDavid du Colombier 			oprange[ASRWCC] = oprange[r];
8157dd7cddfSDavid du Colombier 			break;
8167dd7cddfSDavid du Colombier 		case ASRAW:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
8177dd7cddfSDavid du Colombier 			oprange[ASRAWCC] = oprange[r];
8187dd7cddfSDavid du Colombier 			break;
8197dd7cddfSDavid du Colombier 		case ASUB:	/* SUB Ra,Rb,Rd => subf Rd,ra,rb */
8207dd7cddfSDavid du Colombier 			oprange[ASUB] = oprange[r];
8217dd7cddfSDavid du Colombier 			oprange[ASUBCC] = oprange[r];
8227dd7cddfSDavid du Colombier 			oprange[ASUBV] = oprange[r];
8237dd7cddfSDavid du Colombier 			oprange[ASUBVCC] = oprange[r];
8247dd7cddfSDavid du Colombier 			oprange[ASUBCCC] = oprange[r];
8257dd7cddfSDavid du Colombier 			oprange[ASUBCV] = oprange[r];
8267dd7cddfSDavid du Colombier 			oprange[ASUBCVCC] = oprange[r];
8277dd7cddfSDavid du Colombier 			oprange[ASUBE] = oprange[r];
8287dd7cddfSDavid du Colombier 			oprange[ASUBECC] = oprange[r];
8297dd7cddfSDavid du Colombier 			oprange[ASUBEV] = oprange[r];
8307dd7cddfSDavid du Colombier 			oprange[ASUBEVCC] = oprange[r];
8317dd7cddfSDavid du Colombier 			break;
8327dd7cddfSDavid du Colombier 		case ASYNC:
8337dd7cddfSDavid du Colombier 			oprange[AISYNC] = oprange[r];
8347dd7cddfSDavid du Colombier 			break;
8357dd7cddfSDavid du Colombier 		case ARLWMI:
8367dd7cddfSDavid du Colombier 			oprange[ARLWMICC] = oprange[r];
8377dd7cddfSDavid du Colombier 			oprange[ARLWNM] = oprange[r];
8387dd7cddfSDavid du Colombier 			oprange[ARLWNMCC] = oprange[r];
8397dd7cddfSDavid du Colombier 			break;
8407dd7cddfSDavid du Colombier 		case AFMOVD:
8417dd7cddfSDavid du Colombier 			oprange[AFMOVDCC] = oprange[r];
8427dd7cddfSDavid du Colombier 			oprange[AFMOVDU] = oprange[r];
8437dd7cddfSDavid du Colombier 			oprange[AFMOVS] = oprange[r];
8447dd7cddfSDavid du Colombier 			oprange[AFMOVSU] = oprange[r];
8457dd7cddfSDavid du Colombier 			break;
8467dd7cddfSDavid du Colombier 		case AECIWX:
8477dd7cddfSDavid du Colombier 			oprange[ALWAR] = oprange[r];
8487dd7cddfSDavid du Colombier 			break;
8497dd7cddfSDavid du Colombier 		case ASYSCALL:	/* just the op; flow of control */
8507dd7cddfSDavid du Colombier 			oprange[ARFI] = oprange[r];
851375daca8SDavid du Colombier 			oprange[ARFCI] = oprange[r];
8527dd7cddfSDavid du Colombier 			break;
8537dd7cddfSDavid du Colombier 		case AMOVHBR:
8547dd7cddfSDavid du Colombier 			oprange[AMOVWBR] = oprange[r];
8557dd7cddfSDavid du Colombier 			break;
856*6891d857SDavid du Colombier 		case AFSMOVS:	/* indexed floating loads and stores (fp2) */
857*6891d857SDavid du Colombier 			oprange[AFSMOVSU] = oprange[r];
858*6891d857SDavid du Colombier 			oprange[AFSMOVDU] = oprange[r];
859*6891d857SDavid du Colombier 			oprange[AFXMOVS] = oprange[r];
860*6891d857SDavid du Colombier 			oprange[AFXMOVSU] = oprange[r];
861*6891d857SDavid du Colombier 			oprange[AFXMOVDU] = oprange[r];
862*6891d857SDavid du Colombier 			oprange[AFPMOVS] = oprange[r];
863*6891d857SDavid du Colombier 			oprange[AFPMOVSU] = oprange[r];
864*6891d857SDavid du Colombier 			oprange[AFPMOVDU] = oprange[r];
865*6891d857SDavid du Colombier 			oprange[AFPMOVIW] = oprange[r];
866*6891d857SDavid du Colombier 			break;
867*6891d857SDavid du Colombier 		case AFPMOVD:	/* indexed load/store and moves (fp2) */
868*6891d857SDavid du Colombier 			oprange[AFSMOVD] = oprange[r];
869*6891d857SDavid du Colombier 			oprange[AFXMOVD] = oprange[r];
870*6891d857SDavid du Colombier 			break;
871*6891d857SDavid du Colombier 		case AFMOVSPD:	/* move between fp reg sets (fp2) */
872*6891d857SDavid du Colombier 			oprange[AFMOVPSD] = oprange[r];
873*6891d857SDavid du Colombier 			break;
8747dd7cddfSDavid du Colombier 		case AADD:
8757dd7cddfSDavid du Colombier 		case AANDCC:	/* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
8767dd7cddfSDavid du Colombier 		case ACMP:
8777dd7cddfSDavid du Colombier 		case ACMPU:
8787dd7cddfSDavid du Colombier 		case AEIEIO:
8797dd7cddfSDavid du Colombier 		case ALSW:
8807dd7cddfSDavid du Colombier 		case AMOVB:	/* macro: move byte with sign extension */
8817dd7cddfSDavid du Colombier 		case AMOVBU:	/* macro: move byte with sign extension & update */
8827dd7cddfSDavid du Colombier 		case AMOVW:
8837dd7cddfSDavid du Colombier 		case AMOVFL:
8847dd7cddfSDavid du Colombier 		case AMULLW:	/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
8857dd7cddfSDavid du Colombier 		case ASUBC:	/* op r1,$s,r3; op r1[,r2],r3 */
8867dd7cddfSDavid du Colombier 		case ASTSW:
8877dd7cddfSDavid du Colombier 		case ATLBIE:
8887dd7cddfSDavid du Colombier 		case ATW:
8897dd7cddfSDavid du Colombier 		case AWORD:
8907dd7cddfSDavid du Colombier 		case ANOP:
8917dd7cddfSDavid du Colombier 		case ATEXT:
8927dd7cddfSDavid du Colombier 			break;
8937dd7cddfSDavid du Colombier 		}
8947dd7cddfSDavid du Colombier 	}
8957dd7cddfSDavid du Colombier }
896375daca8SDavid du Colombier 
897375daca8SDavid du Colombier enum{
898375daca8SDavid du Colombier 	ABSD = 0,
899375daca8SDavid du Colombier 	ABSU = 1,
900375daca8SDavid du Colombier 	RELD = 2,
901375daca8SDavid du Colombier 	RELU = 3,
902375daca8SDavid du Colombier };
903375daca8SDavid du Colombier 
904375daca8SDavid du Colombier int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
905375daca8SDavid du Colombier 
906375daca8SDavid du Colombier typedef struct Reloc Reloc;
907375daca8SDavid du Colombier 
908375daca8SDavid du Colombier struct Reloc
909375daca8SDavid du Colombier {
910375daca8SDavid du Colombier 	int n;
911375daca8SDavid du Colombier 	int t;
912375daca8SDavid du Colombier 	uchar *m;
913375daca8SDavid du Colombier 	ulong *a;
914375daca8SDavid du Colombier };
915375daca8SDavid du Colombier 
916375daca8SDavid du Colombier Reloc rels;
917375daca8SDavid du Colombier 
918375daca8SDavid du Colombier static void
grow(Reloc * r)919375daca8SDavid du Colombier grow(Reloc *r)
920375daca8SDavid du Colombier {
921375daca8SDavid du Colombier 	int t;
922375daca8SDavid du Colombier 	uchar *m, *nm;
923375daca8SDavid du Colombier 	ulong *a, *na;
924375daca8SDavid du Colombier 
925375daca8SDavid du Colombier 	t = r->t;
926375daca8SDavid du Colombier 	r->t += 64;
927375daca8SDavid du Colombier 	m = r->m;
928375daca8SDavid du Colombier 	a = r->a;
929375daca8SDavid du Colombier 	r->m = nm = malloc(r->t*sizeof(uchar));
930375daca8SDavid du Colombier 	r->a = na = malloc(r->t*sizeof(ulong));
931375daca8SDavid du Colombier 	memmove(nm, m, t*sizeof(uchar));
932375daca8SDavid du Colombier 	memmove(na, a, t*sizeof(ulong));
933375daca8SDavid du Colombier 	free(m);
934375daca8SDavid du Colombier 	free(a);
935375daca8SDavid du Colombier }
936375daca8SDavid du Colombier 
937375daca8SDavid du Colombier void
dynreloc(Sym * s,long v,int abs,int split,int sext)938375daca8SDavid du Colombier dynreloc(Sym *s, long v, int abs, int split, int sext)
939375daca8SDavid du Colombier {
940375daca8SDavid du Colombier 	int i, k, n;
941375daca8SDavid du Colombier 	uchar *m;
942375daca8SDavid du Colombier 	ulong *a;
943375daca8SDavid du Colombier 	Reloc *r;
944375daca8SDavid du Colombier 
945375daca8SDavid du Colombier 	if(v&3)
946375daca8SDavid du Colombier 		diag("bad relocation address");
947375daca8SDavid du Colombier 	v >>= 2;
948375daca8SDavid du Colombier 	if(s->type == SUNDEF)
949375daca8SDavid du Colombier 		k = abs ? ABSU : RELU;
950375daca8SDavid du Colombier 	else
951375daca8SDavid du Colombier 		k = abs ? ABSD : RELD;
952375daca8SDavid du Colombier 	if(split)
953375daca8SDavid du Colombier 		k += 4;
954375daca8SDavid du Colombier 	if(sext)
955375daca8SDavid du Colombier 		k += 2;
956375daca8SDavid du Colombier 	/* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
957375daca8SDavid du Colombier 	k = modemap[k];
958375daca8SDavid du Colombier 	r = &rels;
959375daca8SDavid du Colombier 	n = r->n;
960375daca8SDavid du Colombier 	if(n >= r->t)
961375daca8SDavid du Colombier 		grow(r);
962375daca8SDavid du Colombier 	m = r->m;
963375daca8SDavid du Colombier 	a = r->a;
964375daca8SDavid du Colombier 	for(i = n; i > 0; i--){
965375daca8SDavid du Colombier 		if(v < a[i-1]){	/* happens occasionally for data */
966375daca8SDavid du Colombier 			m[i] = m[i-1];
967375daca8SDavid du Colombier 			a[i] = a[i-1];
968375daca8SDavid du Colombier 		}
969375daca8SDavid du Colombier 		else
970375daca8SDavid du Colombier 			break;
971375daca8SDavid du Colombier 	}
972375daca8SDavid du Colombier 	m[i] = k;
973375daca8SDavid du Colombier 	a[i] = v;
974375daca8SDavid du Colombier 	r->n++;
975375daca8SDavid du Colombier }
976375daca8SDavid du Colombier 
977375daca8SDavid du Colombier static int
sput(char * s)978375daca8SDavid du Colombier sput(char *s)
979375daca8SDavid du Colombier {
980375daca8SDavid du Colombier 	char *p;
981375daca8SDavid du Colombier 
982375daca8SDavid du Colombier 	p = s;
983375daca8SDavid du Colombier 	while(*s)
984375daca8SDavid du Colombier 		cput(*s++);
985375daca8SDavid du Colombier 	cput(0);
986375daca8SDavid du Colombier 	return s-p+1;
987375daca8SDavid du Colombier }
988375daca8SDavid du Colombier 
989375daca8SDavid du Colombier void
asmdyn()990375daca8SDavid du Colombier asmdyn()
991375daca8SDavid du Colombier {
992375daca8SDavid du Colombier 	int i, n, t, c;
993375daca8SDavid du Colombier 	Sym *s;
994375daca8SDavid du Colombier 	ulong la, ra, *a;
995375daca8SDavid du Colombier 	vlong off;
996375daca8SDavid du Colombier 	uchar *m;
997375daca8SDavid du Colombier 	Reloc *r;
998375daca8SDavid du Colombier 
999375daca8SDavid du Colombier 	cflush();
1000375daca8SDavid du Colombier 	off = seek(cout, 0, 1);
1001375daca8SDavid du Colombier 	lput(0);
1002375daca8SDavid du Colombier 	t = 0;
1003375daca8SDavid du Colombier 	lput(imports);
1004375daca8SDavid du Colombier 	t += 4;
1005375daca8SDavid du Colombier 	for(i = 0; i < NHASH; i++)
1006375daca8SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
1007375daca8SDavid du Colombier 			if(s->type == SUNDEF){
1008375daca8SDavid du Colombier 				lput(s->sig);
1009375daca8SDavid du Colombier 				t += 4;
1010375daca8SDavid du Colombier 				t += sput(s->name);
1011375daca8SDavid du Colombier 			}
1012375daca8SDavid du Colombier 
1013375daca8SDavid du Colombier 	la = 0;
1014375daca8SDavid du Colombier 	r = &rels;
1015375daca8SDavid du Colombier 	n = r->n;
1016375daca8SDavid du Colombier 	m = r->m;
1017375daca8SDavid du Colombier 	a = r->a;
1018375daca8SDavid du Colombier 	lput(n);
1019375daca8SDavid du Colombier 	t += 4;
1020375daca8SDavid du Colombier 	for(i = 0; i < n; i++){
1021375daca8SDavid du Colombier 		ra = *a-la;
1022375daca8SDavid du Colombier 		if(*a < la)
1023375daca8SDavid du Colombier 			diag("bad relocation order");
1024375daca8SDavid du Colombier 		if(ra < 256)
1025375daca8SDavid du Colombier 			c = 0;
1026375daca8SDavid du Colombier 		else if(ra < 65536)
1027375daca8SDavid du Colombier 			c = 1;
1028375daca8SDavid du Colombier 		else
1029375daca8SDavid du Colombier 			c = 2;
1030375daca8SDavid du Colombier 		cput((c<<6)|*m++);
1031375daca8SDavid du Colombier 		t++;
1032375daca8SDavid du Colombier 		if(c == 0){
1033375daca8SDavid du Colombier 			cput(ra);
1034375daca8SDavid du Colombier 			t++;
1035375daca8SDavid du Colombier 		}
1036375daca8SDavid du Colombier 		else if(c == 1){
1037375daca8SDavid du Colombier 			wput(ra);
1038375daca8SDavid du Colombier 			t += 2;
1039375daca8SDavid du Colombier 		}
1040375daca8SDavid du Colombier 		else{
1041375daca8SDavid du Colombier 			lput(ra);
1042375daca8SDavid du Colombier 			t += 4;
1043375daca8SDavid du Colombier 		}
1044375daca8SDavid du Colombier 		la = *a++;
1045375daca8SDavid du Colombier 	}
1046375daca8SDavid du Colombier 
1047375daca8SDavid du Colombier 	cflush();
1048375daca8SDavid du Colombier 	seek(cout, off, 0);
1049375daca8SDavid du Colombier 	lput(t);
1050375daca8SDavid du Colombier 
1051375daca8SDavid du Colombier 	if(debug['v']){
1052375daca8SDavid du Colombier 		Bprint(&bso, "import table entries = %d\n", imports);
1053375daca8SDavid du Colombier 		Bprint(&bso, "export table entries = %d\n", exports);
1054375daca8SDavid du Colombier 	}
1055375daca8SDavid du Colombier }
1056