xref: /plan9-contrib/sys/src/cmd/9l/span.c (revision fbadb1c4d4463e58337ffb1ed396c9caee5d1889)
1*fbadb1c4SDavid du Colombier #include	"l.h"
2*fbadb1c4SDavid du Colombier 
3*fbadb1c4SDavid du Colombier void
span(void)4*fbadb1c4SDavid du Colombier span(void)
5*fbadb1c4SDavid du Colombier {
6*fbadb1c4SDavid du Colombier 	Prog *p, *q;
7*fbadb1c4SDavid du Colombier 	Sym *setext;
8*fbadb1c4SDavid du Colombier 	Optab *o;
9*fbadb1c4SDavid du Colombier 	int m, bflag;
10*fbadb1c4SDavid du Colombier 	vlong c, otxt;
11*fbadb1c4SDavid du Colombier 
12*fbadb1c4SDavid du Colombier 	if(debug['v'])
13*fbadb1c4SDavid du Colombier 		Bprint(&bso, "%5.2f span\n", cputime());
14*fbadb1c4SDavid du Colombier 	Bflush(&bso);
15*fbadb1c4SDavid du Colombier 
16*fbadb1c4SDavid du Colombier 	bflag = 0;
17*fbadb1c4SDavid du Colombier 	c = INITTEXT;
18*fbadb1c4SDavid du Colombier 	otxt = c;
19*fbadb1c4SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
20*fbadb1c4SDavid du Colombier 		p->pc = c;
21*fbadb1c4SDavid du Colombier 		o = oplook(p);
22*fbadb1c4SDavid du Colombier 		m = o->size;
23*fbadb1c4SDavid du Colombier 		if(m == 0) {
24*fbadb1c4SDavid du Colombier 			if(p->as == ATEXT) {
25*fbadb1c4SDavid du Colombier 				curtext = p;
26*fbadb1c4SDavid du Colombier 				autosize = p->to.offset + 8;
27*fbadb1c4SDavid du Colombier 				if(p->from3.type == D_CONST) {
28*fbadb1c4SDavid du Colombier 					if(p->from3.offset & 3)
29*fbadb1c4SDavid du Colombier 						diag("illegal origin\n%P", p);
30*fbadb1c4SDavid du Colombier 					if(c > p->from3.offset)
31*fbadb1c4SDavid du Colombier 						diag("passed origin (#%llux)\n%P", c, p);
32*fbadb1c4SDavid du Colombier 					else
33*fbadb1c4SDavid du Colombier 						c = p->from3.offset;
34*fbadb1c4SDavid du Colombier 					p->pc = c;
35*fbadb1c4SDavid du Colombier 				}
36*fbadb1c4SDavid du Colombier 				if(p->from.sym != S)
37*fbadb1c4SDavid du Colombier 					p->from.sym->value = c;
38*fbadb1c4SDavid du Colombier 				/* need passes to resolve branches? */
39*fbadb1c4SDavid du Colombier 				if(c-otxt >= (1L<<15))
40*fbadb1c4SDavid du Colombier 					bflag = c;
41*fbadb1c4SDavid du Colombier 				otxt = c;
42*fbadb1c4SDavid du Colombier 				continue;
43*fbadb1c4SDavid du Colombier 			}
44*fbadb1c4SDavid du Colombier 			if(p->as != ANOP)
45*fbadb1c4SDavid du Colombier 				diag("zero-width instruction\n%P", p);
46*fbadb1c4SDavid du Colombier 			continue;
47*fbadb1c4SDavid du Colombier 		}
48*fbadb1c4SDavid du Colombier 		c += m;
49*fbadb1c4SDavid du Colombier 	}
50*fbadb1c4SDavid du Colombier 
51*fbadb1c4SDavid du Colombier 	/*
52*fbadb1c4SDavid du Colombier 	 * if any procedure is large enough to
53*fbadb1c4SDavid du Colombier 	 * generate a large SBRA branch, then
54*fbadb1c4SDavid du Colombier 	 * generate extra passes putting branches
55*fbadb1c4SDavid du Colombier 	 * around jmps to fix. this is rare.
56*fbadb1c4SDavid du Colombier 	 */
57*fbadb1c4SDavid du Colombier 	while(bflag) {
58*fbadb1c4SDavid du Colombier 		if(debug['v'])
59*fbadb1c4SDavid du Colombier 			Bprint(&bso, "%5.2f span1\n", cputime());
60*fbadb1c4SDavid du Colombier 		bflag = 0;
61*fbadb1c4SDavid du Colombier 		c = INITTEXT;
62*fbadb1c4SDavid du Colombier 		for(p = firstp; p != P; p = p->link) {
63*fbadb1c4SDavid du Colombier 			p->pc = c;
64*fbadb1c4SDavid du Colombier 			o = oplook(p);
65*fbadb1c4SDavid du Colombier 			if((o->type == 16 || o->type == 17) && p->cond) {
66*fbadb1c4SDavid du Colombier 				otxt = p->cond->pc - c;
67*fbadb1c4SDavid du Colombier 				if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
68*fbadb1c4SDavid du Colombier 					q = prg();
69*fbadb1c4SDavid du Colombier 					q->link = p->link;
70*fbadb1c4SDavid du Colombier 					p->link = q;
71*fbadb1c4SDavid du Colombier 					q->as = ABR;
72*fbadb1c4SDavid du Colombier 					q->to.type = D_BRANCH;
73*fbadb1c4SDavid du Colombier 					q->cond = p->cond;
74*fbadb1c4SDavid du Colombier 					p->cond = q;
75*fbadb1c4SDavid du Colombier 					q = prg();
76*fbadb1c4SDavid du Colombier 					q->link = p->link;
77*fbadb1c4SDavid du Colombier 					p->link = q;
78*fbadb1c4SDavid du Colombier 					q->as = ABR;
79*fbadb1c4SDavid du Colombier 					q->to.type = D_BRANCH;
80*fbadb1c4SDavid du Colombier 					q->cond = q->link->link;
81*fbadb1c4SDavid du Colombier 					addnop(p->link);
82*fbadb1c4SDavid du Colombier 					addnop(p);
83*fbadb1c4SDavid du Colombier 					bflag = 1;
84*fbadb1c4SDavid du Colombier 				}
85*fbadb1c4SDavid du Colombier 			}
86*fbadb1c4SDavid du Colombier 			m = o->size;
87*fbadb1c4SDavid du Colombier 			if(m == 0) {
88*fbadb1c4SDavid du Colombier 				if(p->as == ATEXT) {
89*fbadb1c4SDavid du Colombier 					curtext = p;
90*fbadb1c4SDavid du Colombier 					autosize = p->to.offset + 8;
91*fbadb1c4SDavid du Colombier 					if(p->from.sym != S)
92*fbadb1c4SDavid du Colombier 						p->from.sym->value = c;
93*fbadb1c4SDavid du Colombier 					continue;
94*fbadb1c4SDavid du Colombier 				}
95*fbadb1c4SDavid du Colombier 				if(p->as != ANOP)
96*fbadb1c4SDavid du Colombier 					diag("zero-width instruction\n%P", p);
97*fbadb1c4SDavid du Colombier 				continue;
98*fbadb1c4SDavid du Colombier 			}
99*fbadb1c4SDavid du Colombier 			c += m;
100*fbadb1c4SDavid du Colombier 		}
101*fbadb1c4SDavid du Colombier 	}
102*fbadb1c4SDavid du Colombier 
103*fbadb1c4SDavid du Colombier 	c = rnd(c, 8);
104*fbadb1c4SDavid du Colombier 
105*fbadb1c4SDavid du Colombier 	setext = lookup("etext", 0);
106*fbadb1c4SDavid du Colombier 	if(setext != S) {
107*fbadb1c4SDavid du Colombier 		setext->value = c;
108*fbadb1c4SDavid du Colombier 		textsize = c - INITTEXT;
109*fbadb1c4SDavid du Colombier 	}
110*fbadb1c4SDavid du Colombier 	if(INITRND)
111*fbadb1c4SDavid du Colombier 		INITDAT = rnd(c, INITRND);
112*fbadb1c4SDavid du Colombier 	if(debug['v'])
113*fbadb1c4SDavid du Colombier 		Bprint(&bso, "tsize = %llux\n", textsize);
114*fbadb1c4SDavid du Colombier 	Bflush(&bso);
115*fbadb1c4SDavid du Colombier }
116*fbadb1c4SDavid du Colombier 
117*fbadb1c4SDavid du Colombier void
xdefine(char * p,int t,vlong v)118*fbadb1c4SDavid du Colombier xdefine(char *p, int t, vlong v)
119*fbadb1c4SDavid du Colombier {
120*fbadb1c4SDavid du Colombier 	Sym *s;
121*fbadb1c4SDavid du Colombier 
122*fbadb1c4SDavid du Colombier 	s = lookup(p, 0);
123*fbadb1c4SDavid du Colombier 	if(s->type == 0 || s->type == SXREF) {
124*fbadb1c4SDavid du Colombier 		s->type = t;
125*fbadb1c4SDavid du Colombier 		s->value = v;
126*fbadb1c4SDavid du Colombier 	}
127*fbadb1c4SDavid du Colombier }
128*fbadb1c4SDavid du Colombier 
129*fbadb1c4SDavid du Colombier vlong
vregoff(Adr * a)130*fbadb1c4SDavid du Colombier vregoff(Adr *a)
131*fbadb1c4SDavid du Colombier {
132*fbadb1c4SDavid du Colombier 
133*fbadb1c4SDavid du Colombier 	instoffset = 0;
134*fbadb1c4SDavid du Colombier 	aclass(a);
135*fbadb1c4SDavid du Colombier 	return instoffset;
136*fbadb1c4SDavid du Colombier }
137*fbadb1c4SDavid du Colombier 
138*fbadb1c4SDavid du Colombier long
regoff(Adr * a)139*fbadb1c4SDavid du Colombier regoff(Adr *a)
140*fbadb1c4SDavid du Colombier {
141*fbadb1c4SDavid du Colombier 	return vregoff(a);
142*fbadb1c4SDavid du Colombier }
143*fbadb1c4SDavid du Colombier 
144*fbadb1c4SDavid du Colombier int
isint32(vlong v)145*fbadb1c4SDavid du Colombier isint32(vlong v)
146*fbadb1c4SDavid du Colombier {
147*fbadb1c4SDavid du Colombier 	long l;
148*fbadb1c4SDavid du Colombier 
149*fbadb1c4SDavid du Colombier 	l = v;
150*fbadb1c4SDavid du Colombier 	return (vlong)l == v;
151*fbadb1c4SDavid du Colombier }
152*fbadb1c4SDavid du Colombier 
153*fbadb1c4SDavid du Colombier int
isuint32(uvlong v)154*fbadb1c4SDavid du Colombier isuint32(uvlong v)
155*fbadb1c4SDavid du Colombier {
156*fbadb1c4SDavid du Colombier 	ulong l;
157*fbadb1c4SDavid du Colombier 
158*fbadb1c4SDavid du Colombier 	l = v;
159*fbadb1c4SDavid du Colombier 	return (uvlong)l == v;
160*fbadb1c4SDavid du Colombier }
161*fbadb1c4SDavid du Colombier 
162*fbadb1c4SDavid du Colombier int
aclass(Adr * a)163*fbadb1c4SDavid du Colombier aclass(Adr *a)
164*fbadb1c4SDavid du Colombier {
165*fbadb1c4SDavid du Colombier 	Sym *s;
166*fbadb1c4SDavid du Colombier 	int t;
167*fbadb1c4SDavid du Colombier 
168*fbadb1c4SDavid du Colombier 	switch(a->type) {
169*fbadb1c4SDavid du Colombier 	case D_NONE:
170*fbadb1c4SDavid du Colombier 		return C_NONE;
171*fbadb1c4SDavid du Colombier 
172*fbadb1c4SDavid du Colombier 	case D_REG:
173*fbadb1c4SDavid du Colombier 		return C_REG;
174*fbadb1c4SDavid du Colombier 
175*fbadb1c4SDavid du Colombier 	case D_FREG:
176*fbadb1c4SDavid du Colombier 		return C_FREG;
177*fbadb1c4SDavid du Colombier 
178*fbadb1c4SDavid du Colombier 	case D_CREG:
179*fbadb1c4SDavid du Colombier 		return C_CREG;
180*fbadb1c4SDavid du Colombier 
181*fbadb1c4SDavid du Colombier 	case D_SPR:
182*fbadb1c4SDavid du Colombier 		if(a->offset == D_LR)
183*fbadb1c4SDavid du Colombier 			return C_LR;
184*fbadb1c4SDavid du Colombier 		if(a->offset == D_XER)
185*fbadb1c4SDavid du Colombier 			return C_XER;
186*fbadb1c4SDavid du Colombier 		if(a->offset == D_CTR)
187*fbadb1c4SDavid du Colombier 			return C_CTR;
188*fbadb1c4SDavid du Colombier 		return C_SPR;
189*fbadb1c4SDavid du Colombier 
190*fbadb1c4SDavid du Colombier 	case D_DCR:
191*fbadb1c4SDavid du Colombier 		return C_SPR;
192*fbadb1c4SDavid du Colombier 
193*fbadb1c4SDavid du Colombier 	case D_FPSCR:
194*fbadb1c4SDavid du Colombier 		return C_FPSCR;
195*fbadb1c4SDavid du Colombier 
196*fbadb1c4SDavid du Colombier 	case D_MSR:
197*fbadb1c4SDavid du Colombier 		return C_MSR;
198*fbadb1c4SDavid du Colombier 
199*fbadb1c4SDavid du Colombier 	case D_OREG:
200*fbadb1c4SDavid du Colombier 		switch(a->name) {
201*fbadb1c4SDavid du Colombier 		case D_EXTERN:
202*fbadb1c4SDavid du Colombier 		case D_STATIC:
203*fbadb1c4SDavid du Colombier 			if(a->sym == S)
204*fbadb1c4SDavid du Colombier 				break;
205*fbadb1c4SDavid du Colombier 			t = a->sym->type;
206*fbadb1c4SDavid du Colombier 			if(t == 0 || t == SXREF) {
207*fbadb1c4SDavid du Colombier 				diag("undefined external: %s in %s",
208*fbadb1c4SDavid du Colombier 					a->sym->name, TNAME);
209*fbadb1c4SDavid du Colombier 				a->sym->type = SDATA;
210*fbadb1c4SDavid du Colombier 			}
211*fbadb1c4SDavid du Colombier 			if(dlm){
212*fbadb1c4SDavid du Colombier 				instoffset = a->sym->value + a->offset;
213*fbadb1c4SDavid du Colombier 				switch(a->sym->type){
214*fbadb1c4SDavid du Colombier 				case STEXT:
215*fbadb1c4SDavid du Colombier 				case SLEAF:
216*fbadb1c4SDavid du Colombier 				case SCONST:
217*fbadb1c4SDavid du Colombier 				case SUNDEF:
218*fbadb1c4SDavid du Colombier 					break;
219*fbadb1c4SDavid du Colombier 				default:
220*fbadb1c4SDavid du Colombier 					instoffset += INITDAT;
221*fbadb1c4SDavid du Colombier 				}
222*fbadb1c4SDavid du Colombier 				return C_ADDR;
223*fbadb1c4SDavid du Colombier 			}
224*fbadb1c4SDavid du Colombier 			instoffset = a->sym->value + a->offset - BIG;
225*fbadb1c4SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
226*fbadb1c4SDavid du Colombier 				return C_SEXT;
227*fbadb1c4SDavid du Colombier 			return C_LEXT;
228*fbadb1c4SDavid du Colombier 		case D_AUTO:
229*fbadb1c4SDavid du Colombier 			instoffset = autosize + a->offset;
230*fbadb1c4SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
231*fbadb1c4SDavid du Colombier 				return C_SAUTO;
232*fbadb1c4SDavid du Colombier 			return C_LAUTO;
233*fbadb1c4SDavid du Colombier 		case D_PARAM:
234*fbadb1c4SDavid du Colombier 			instoffset = autosize + a->offset + 8L;
235*fbadb1c4SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
236*fbadb1c4SDavid du Colombier 				return C_SAUTO;
237*fbadb1c4SDavid du Colombier 			return C_LAUTO;
238*fbadb1c4SDavid du Colombier 		case D_NONE:
239*fbadb1c4SDavid du Colombier 			instoffset = a->offset;
240*fbadb1c4SDavid du Colombier 			if(instoffset == 0)
241*fbadb1c4SDavid du Colombier 				return C_ZOREG;
242*fbadb1c4SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
243*fbadb1c4SDavid du Colombier 				return C_SOREG;
244*fbadb1c4SDavid du Colombier 			return C_LOREG;
245*fbadb1c4SDavid du Colombier 		}
246*fbadb1c4SDavid du Colombier 		return C_GOK;
247*fbadb1c4SDavid du Colombier 
248*fbadb1c4SDavid du Colombier 	case D_OPT:
249*fbadb1c4SDavid du Colombier 		instoffset = a->offset & 31L;
250*fbadb1c4SDavid du Colombier 		if(a->name == D_NONE)
251*fbadb1c4SDavid du Colombier 			return C_SCON;
252*fbadb1c4SDavid du Colombier 		return C_GOK;
253*fbadb1c4SDavid du Colombier 
254*fbadb1c4SDavid du Colombier 	case D_CONST:
255*fbadb1c4SDavid du Colombier 		switch(a->name) {
256*fbadb1c4SDavid du Colombier 
257*fbadb1c4SDavid du Colombier 		case D_NONE:
258*fbadb1c4SDavid du Colombier 			instoffset = a->offset;
259*fbadb1c4SDavid du Colombier 		consize:
260*fbadb1c4SDavid du Colombier 			if(instoffset >= 0) {
261*fbadb1c4SDavid du Colombier 				if(instoffset == 0)
262*fbadb1c4SDavid du Colombier 					return C_ZCON;
263*fbadb1c4SDavid du Colombier 				if(instoffset <= 0x7fff)
264*fbadb1c4SDavid du Colombier 					return C_SCON;
265*fbadb1c4SDavid du Colombier 				if(instoffset <= 0xffff)
266*fbadb1c4SDavid du Colombier 					return C_ANDCON;
267*fbadb1c4SDavid du Colombier 				if((instoffset & 0xffff) == 0 && isuint32(instoffset))	/* && (instoffset & (1<<31)) == 0) */
268*fbadb1c4SDavid du Colombier 					return C_UCON;
269*fbadb1c4SDavid du Colombier 				if(isint32(instoffset) || isuint32(instoffset))
270*fbadb1c4SDavid du Colombier 					return C_LCON;
271*fbadb1c4SDavid du Colombier 				return C_DCON;
272*fbadb1c4SDavid du Colombier 			}
273*fbadb1c4SDavid du Colombier 			if(instoffset >= -0x8000)
274*fbadb1c4SDavid du Colombier 				return C_ADDCON;
275*fbadb1c4SDavid du Colombier 			if((instoffset & 0xffff) == 0 && isint32(instoffset))
276*fbadb1c4SDavid du Colombier 				return C_UCON;
277*fbadb1c4SDavid du Colombier 			if(isint32(instoffset))
278*fbadb1c4SDavid du Colombier 				return C_LCON;
279*fbadb1c4SDavid du Colombier 			return C_DCON;
280*fbadb1c4SDavid du Colombier 
281*fbadb1c4SDavid du Colombier 		case D_EXTERN:
282*fbadb1c4SDavid du Colombier 		case D_STATIC:
283*fbadb1c4SDavid du Colombier 			s = a->sym;
284*fbadb1c4SDavid du Colombier 			if(s == S)
285*fbadb1c4SDavid du Colombier 				break;
286*fbadb1c4SDavid du Colombier 			t = s->type;
287*fbadb1c4SDavid du Colombier 			if(t == 0 || t == SXREF) {
288*fbadb1c4SDavid du Colombier 				diag("undefined external: %s in %s",
289*fbadb1c4SDavid du Colombier 					s->name, TNAME);
290*fbadb1c4SDavid du Colombier 				s->type = SDATA;
291*fbadb1c4SDavid du Colombier 			}
292*fbadb1c4SDavid du Colombier 			if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
293*fbadb1c4SDavid du Colombier 				instoffset = s->value + a->offset;
294*fbadb1c4SDavid du Colombier 				return C_LCON;
295*fbadb1c4SDavid du Colombier 			}
296*fbadb1c4SDavid du Colombier 			if(s->type == SCONST) {
297*fbadb1c4SDavid du Colombier 				instoffset = s->value + a->offset;
298*fbadb1c4SDavid du Colombier 				if(dlm)
299*fbadb1c4SDavid du Colombier 					return C_LCON;
300*fbadb1c4SDavid du Colombier 				goto consize;
301*fbadb1c4SDavid du Colombier 			}
302*fbadb1c4SDavid du Colombier 			if(!dlm){
303*fbadb1c4SDavid du Colombier 				instoffset = s->value + a->offset - BIG;
304*fbadb1c4SDavid du Colombier 				if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
305*fbadb1c4SDavid du Colombier 					return C_SECON;
306*fbadb1c4SDavid du Colombier 			}
307*fbadb1c4SDavid du Colombier 			instoffset = s->value + a->offset + INITDAT;
308*fbadb1c4SDavid du Colombier 			if(dlm)
309*fbadb1c4SDavid du Colombier 				return C_LCON;
310*fbadb1c4SDavid du Colombier 			/* not sure why this barfs */
311*fbadb1c4SDavid du Colombier 			return C_LCON;
312*fbadb1c4SDavid du Colombier 		/*
313*fbadb1c4SDavid du Colombier 			if(instoffset == 0)
314*fbadb1c4SDavid du Colombier 				return C_ZCON;
315*fbadb1c4SDavid du Colombier 			if(instoffset >= -0x8000 && instoffset <= 0xffff)
316*fbadb1c4SDavid du Colombier 				return C_SCON;
317*fbadb1c4SDavid du Colombier 			if((instoffset & 0xffff) == 0)
318*fbadb1c4SDavid du Colombier 				return C_UCON;
319*fbadb1c4SDavid du Colombier 			return C_LCON;
320*fbadb1c4SDavid du Colombier 		*/
321*fbadb1c4SDavid du Colombier 
322*fbadb1c4SDavid du Colombier 		case D_AUTO:
323*fbadb1c4SDavid du Colombier 			instoffset = autosize + a->offset;
324*fbadb1c4SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
325*fbadb1c4SDavid du Colombier 				return C_SACON;
326*fbadb1c4SDavid du Colombier 			return C_LACON;
327*fbadb1c4SDavid du Colombier 
328*fbadb1c4SDavid du Colombier 		case D_PARAM:
329*fbadb1c4SDavid du Colombier 			instoffset = autosize + a->offset + 8L;
330*fbadb1c4SDavid du Colombier 			if(instoffset >= -BIG && instoffset < BIG)
331*fbadb1c4SDavid du Colombier 				return C_SACON;
332*fbadb1c4SDavid du Colombier 			return C_LACON;
333*fbadb1c4SDavid du Colombier 		}
334*fbadb1c4SDavid du Colombier 		return C_GOK;
335*fbadb1c4SDavid du Colombier 
336*fbadb1c4SDavid du Colombier 	case D_BRANCH:
337*fbadb1c4SDavid du Colombier 		return C_SBRA;
338*fbadb1c4SDavid du Colombier 	}
339*fbadb1c4SDavid du Colombier 	return C_GOK;
340*fbadb1c4SDavid du Colombier }
341*fbadb1c4SDavid du Colombier 
342*fbadb1c4SDavid du Colombier Optab*
oplook(Prog * p)343*fbadb1c4SDavid du Colombier oplook(Prog *p)
344*fbadb1c4SDavid du Colombier {
345*fbadb1c4SDavid du Colombier 	int a1, a2, a3, a4, r;
346*fbadb1c4SDavid du Colombier 	char *c1, *c3, *c4;
347*fbadb1c4SDavid du Colombier 	Optab *o, *e;
348*fbadb1c4SDavid du Colombier 
349*fbadb1c4SDavid du Colombier 	a1 = p->optab;
350*fbadb1c4SDavid du Colombier 	if(a1)
351*fbadb1c4SDavid du Colombier 		return optab+(a1-1);
352*fbadb1c4SDavid du Colombier 	a1 = p->from.class;
353*fbadb1c4SDavid du Colombier 	if(a1 == 0) {
354*fbadb1c4SDavid du Colombier 		a1 = aclass(&p->from) + 1;
355*fbadb1c4SDavid du Colombier 		p->from.class = a1;
356*fbadb1c4SDavid du Colombier 	}
357*fbadb1c4SDavid du Colombier 	a1--;
358*fbadb1c4SDavid du Colombier 	a3 = p->from3.class;
359*fbadb1c4SDavid du Colombier 	if(a3 == 0) {
360*fbadb1c4SDavid du Colombier 		a3 = aclass(&p->from3) + 1;
361*fbadb1c4SDavid du Colombier 		p->from3.class = a3;
362*fbadb1c4SDavid du Colombier 	}
363*fbadb1c4SDavid du Colombier 	a3--;
364*fbadb1c4SDavid du Colombier 	a4 = p->to.class;
365*fbadb1c4SDavid du Colombier 	if(a4 == 0) {
366*fbadb1c4SDavid du Colombier 		a4 = aclass(&p->to) + 1;
367*fbadb1c4SDavid du Colombier 		p->to.class = a4;
368*fbadb1c4SDavid du Colombier 	}
369*fbadb1c4SDavid du Colombier 	a4--;
370*fbadb1c4SDavid du Colombier 	a2 = C_NONE;
371*fbadb1c4SDavid du Colombier 	if(p->reg != NREG)
372*fbadb1c4SDavid du Colombier 		a2 = C_REG;
373*fbadb1c4SDavid du Colombier 	r = p->as;
374*fbadb1c4SDavid du Colombier 	o = oprange[r].start;
375*fbadb1c4SDavid du Colombier 	if(o == 0)
376*fbadb1c4SDavid du Colombier 		o = oprange[r].stop; /* just generate an error */
377*fbadb1c4SDavid du Colombier 	e = oprange[r].stop;
378*fbadb1c4SDavid du Colombier 	c1 = xcmp[a1];
379*fbadb1c4SDavid du Colombier 	c3 = xcmp[a3];
380*fbadb1c4SDavid du Colombier 	c4 = xcmp[a4];
381*fbadb1c4SDavid du Colombier 	for(; o<e; o++)
382*fbadb1c4SDavid du Colombier 		if(o->a2 == a2)
383*fbadb1c4SDavid du Colombier 		if(c1[o->a1])
384*fbadb1c4SDavid du Colombier 		if(c3[o->a3])
385*fbadb1c4SDavid du Colombier 		if(c4[o->a4]) {
386*fbadb1c4SDavid du Colombier 			p->optab = (o-optab)+1;
387*fbadb1c4SDavid du Colombier 			return o;
388*fbadb1c4SDavid du Colombier 		}
389*fbadb1c4SDavid du Colombier 	diag("illegal combination %A %R %R %R %R",
390*fbadb1c4SDavid du Colombier 		p->as, a1, a2, a3, a4);
391*fbadb1c4SDavid du Colombier 	if(1||!debug['a'])
392*fbadb1c4SDavid du Colombier 		prasm(p);
393*fbadb1c4SDavid du Colombier 	if(o == 0)
394*fbadb1c4SDavid du Colombier 		errorexit();
395*fbadb1c4SDavid du Colombier 	return o;
396*fbadb1c4SDavid du Colombier }
397*fbadb1c4SDavid du Colombier 
398*fbadb1c4SDavid du Colombier int
cmp(int a,int b)399*fbadb1c4SDavid du Colombier cmp(int a, int b)
400*fbadb1c4SDavid du Colombier {
401*fbadb1c4SDavid du Colombier 
402*fbadb1c4SDavid du Colombier 	if(a == b)
403*fbadb1c4SDavid du Colombier 		return 1;
404*fbadb1c4SDavid du Colombier 	switch(a) {
405*fbadb1c4SDavid du Colombier 	case C_LCON:
406*fbadb1c4SDavid du Colombier 		if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
407*fbadb1c4SDavid du Colombier 			return 1;
408*fbadb1c4SDavid du Colombier 		break;
409*fbadb1c4SDavid du Colombier 	case C_ADDCON:
410*fbadb1c4SDavid du Colombier 		if(b == C_ZCON || b == C_SCON)
411*fbadb1c4SDavid du Colombier 			return 1;
412*fbadb1c4SDavid du Colombier 		break;
413*fbadb1c4SDavid du Colombier 	case C_ANDCON:
414*fbadb1c4SDavid du Colombier 		if(b == C_ZCON || b == C_SCON)
415*fbadb1c4SDavid du Colombier 			return 1;
416*fbadb1c4SDavid du Colombier 		break;
417*fbadb1c4SDavid du Colombier 	case C_SPR:
418*fbadb1c4SDavid du Colombier 		if(b == C_LR || b == C_XER || b == C_CTR)
419*fbadb1c4SDavid du Colombier 			return 1;
420*fbadb1c4SDavid du Colombier 		break;
421*fbadb1c4SDavid du Colombier 	case C_UCON:
422*fbadb1c4SDavid du Colombier 		if(b == C_ZCON)
423*fbadb1c4SDavid du Colombier 			return 1;
424*fbadb1c4SDavid du Colombier 		break;
425*fbadb1c4SDavid du Colombier 	case C_SCON:
426*fbadb1c4SDavid du Colombier 		if(b == C_ZCON)
427*fbadb1c4SDavid du Colombier 			return 1;
428*fbadb1c4SDavid du Colombier 		break;
429*fbadb1c4SDavid du Colombier 	case C_LACON:
430*fbadb1c4SDavid du Colombier 		if(b == C_SACON)
431*fbadb1c4SDavid du Colombier 			return 1;
432*fbadb1c4SDavid du Colombier 		break;
433*fbadb1c4SDavid du Colombier 	case C_LBRA:
434*fbadb1c4SDavid du Colombier 		if(b == C_SBRA)
435*fbadb1c4SDavid du Colombier 			return 1;
436*fbadb1c4SDavid du Colombier 		break;
437*fbadb1c4SDavid du Colombier 	case C_LEXT:
438*fbadb1c4SDavid du Colombier 		if(b == C_SEXT)
439*fbadb1c4SDavid du Colombier 			return 1;
440*fbadb1c4SDavid du Colombier 		break;
441*fbadb1c4SDavid du Colombier 	case C_LAUTO:
442*fbadb1c4SDavid du Colombier 		if(b == C_SAUTO)
443*fbadb1c4SDavid du Colombier 			return 1;
444*fbadb1c4SDavid du Colombier 		break;
445*fbadb1c4SDavid du Colombier 	case C_REG:
446*fbadb1c4SDavid du Colombier 		if(b == C_ZCON)
447*fbadb1c4SDavid du Colombier 			return r0iszero;
448*fbadb1c4SDavid du Colombier 		break;
449*fbadb1c4SDavid du Colombier 	case C_LOREG:
450*fbadb1c4SDavid du Colombier 		if(b == C_ZOREG || b == C_SOREG)
451*fbadb1c4SDavid du Colombier 			return 1;
452*fbadb1c4SDavid du Colombier 		break;
453*fbadb1c4SDavid du Colombier 	case C_SOREG:
454*fbadb1c4SDavid du Colombier 		if(b == C_ZOREG)
455*fbadb1c4SDavid du Colombier 			return 1;
456*fbadb1c4SDavid du Colombier 		break;
457*fbadb1c4SDavid du Colombier 
458*fbadb1c4SDavid du Colombier 	case C_ANY:
459*fbadb1c4SDavid du Colombier 		return 1;
460*fbadb1c4SDavid du Colombier 	}
461*fbadb1c4SDavid du Colombier 	return 0;
462*fbadb1c4SDavid du Colombier }
463*fbadb1c4SDavid du Colombier 
464*fbadb1c4SDavid du Colombier int
ocmp(void * a1,void * a2)465*fbadb1c4SDavid du Colombier ocmp(void *a1, void *a2)
466*fbadb1c4SDavid du Colombier {
467*fbadb1c4SDavid du Colombier 	Optab *p1, *p2;
468*fbadb1c4SDavid du Colombier 	int n;
469*fbadb1c4SDavid du Colombier 
470*fbadb1c4SDavid du Colombier 	p1 = a1;
471*fbadb1c4SDavid du Colombier 	p2 = a2;
472*fbadb1c4SDavid du Colombier 	n = p1->as - p2->as;
473*fbadb1c4SDavid du Colombier 	if(n)
474*fbadb1c4SDavid du Colombier 		return n;
475*fbadb1c4SDavid du Colombier 	n = p1->a1 - p2->a1;
476*fbadb1c4SDavid du Colombier 	if(n)
477*fbadb1c4SDavid du Colombier 		return n;
478*fbadb1c4SDavid du Colombier 	n = p1->a2 - p2->a2;
479*fbadb1c4SDavid du Colombier 	if(n)
480*fbadb1c4SDavid du Colombier 		return n;
481*fbadb1c4SDavid du Colombier 	n = p1->a3 - p2->a3;
482*fbadb1c4SDavid du Colombier 	if(n)
483*fbadb1c4SDavid du Colombier 		return n;
484*fbadb1c4SDavid du Colombier 	n = p1->a4 - p2->a4;
485*fbadb1c4SDavid du Colombier 	if(n)
486*fbadb1c4SDavid du Colombier 		return n;
487*fbadb1c4SDavid du Colombier 	return 0;
488*fbadb1c4SDavid du Colombier }
489*fbadb1c4SDavid du Colombier 
490*fbadb1c4SDavid du Colombier void
buildop(void)491*fbadb1c4SDavid du Colombier buildop(void)
492*fbadb1c4SDavid du Colombier {
493*fbadb1c4SDavid du Colombier 	int i, n, r;
494*fbadb1c4SDavid du Colombier 
495*fbadb1c4SDavid du Colombier 	for(i=0; i<C_NCLASS; i++)
496*fbadb1c4SDavid du Colombier 		for(n=0; n<C_NCLASS; n++)
497*fbadb1c4SDavid du Colombier 			xcmp[i][n] = cmp(n, i);
498*fbadb1c4SDavid du Colombier 	for(n=0; optab[n].as != AXXX; n++)
499*fbadb1c4SDavid du Colombier 		;
500*fbadb1c4SDavid du Colombier 	qsort(optab, n, sizeof(optab[0]), ocmp);
501*fbadb1c4SDavid du Colombier 	for(i=0; i<n; i++) {
502*fbadb1c4SDavid du Colombier 		r = optab[i].as;
503*fbadb1c4SDavid du Colombier 		oprange[r].start = optab+i;
504*fbadb1c4SDavid du Colombier 		while(optab[i].as == r)
505*fbadb1c4SDavid du Colombier 			i++;
506*fbadb1c4SDavid du Colombier 		oprange[r].stop = optab+i;
507*fbadb1c4SDavid du Colombier 		i--;
508*fbadb1c4SDavid du Colombier 
509*fbadb1c4SDavid du Colombier 		switch(r)
510*fbadb1c4SDavid du Colombier 		{
511*fbadb1c4SDavid du Colombier 		default:
512*fbadb1c4SDavid du Colombier 			diag("unknown op in build: %A", r);
513*fbadb1c4SDavid du Colombier 			errorexit();
514*fbadb1c4SDavid du Colombier 		case ADCBF:	/* unary indexed: op (b+a); op (b) */
515*fbadb1c4SDavid du Colombier 			oprange[ADCBI] = oprange[r];
516*fbadb1c4SDavid du Colombier 			oprange[ADCBST] = oprange[r];
517*fbadb1c4SDavid du Colombier 			oprange[ADCBT] = oprange[r];
518*fbadb1c4SDavid du Colombier 			oprange[ADCBTST] = oprange[r];
519*fbadb1c4SDavid du Colombier 			oprange[ADCBZ] = oprange[r];
520*fbadb1c4SDavid du Colombier 			oprange[AICBI] = oprange[r];
521*fbadb1c4SDavid du Colombier 			break;
522*fbadb1c4SDavid du Colombier 		case AECOWX:	/* indexed store: op s,(b+a); op s,(b) */
523*fbadb1c4SDavid du Colombier 			oprange[ASTWCCC] = oprange[r];
524*fbadb1c4SDavid du Colombier 			break;
525*fbadb1c4SDavid du Colombier 		case AREM:	/* macro */
526*fbadb1c4SDavid du Colombier 			oprange[AREMCC] = oprange[r];
527*fbadb1c4SDavid du Colombier 			oprange[AREMV] = oprange[r];
528*fbadb1c4SDavid du Colombier 			oprange[AREMVCC] = oprange[r];
529*fbadb1c4SDavid du Colombier 			oprange[AREMU] = oprange[r];
530*fbadb1c4SDavid du Colombier 			oprange[AREMUCC] = oprange[r];
531*fbadb1c4SDavid du Colombier 			oprange[AREMUV] = oprange[r];
532*fbadb1c4SDavid du Colombier 			oprange[AREMUVCC] = oprange[r];
533*fbadb1c4SDavid du Colombier 			break;
534*fbadb1c4SDavid du Colombier 		case AREMD:
535*fbadb1c4SDavid du Colombier 			oprange[AREMDCC] = oprange[r];
536*fbadb1c4SDavid du Colombier 			oprange[AREMDV] = oprange[r];
537*fbadb1c4SDavid du Colombier 			oprange[AREMDVCC] = oprange[r];
538*fbadb1c4SDavid du Colombier 			oprange[AREMDU] = oprange[r];
539*fbadb1c4SDavid du Colombier 			oprange[AREMDUCC] = oprange[r];
540*fbadb1c4SDavid du Colombier 			oprange[AREMDUV] = oprange[r];
541*fbadb1c4SDavid du Colombier 			oprange[AREMDUVCC] = oprange[r];
542*fbadb1c4SDavid du Colombier 			break;
543*fbadb1c4SDavid du Colombier 		case ADIVW:	/* op Rb[,Ra],Rd */
544*fbadb1c4SDavid du Colombier 			oprange[AMULHW] = oprange[r];
545*fbadb1c4SDavid du Colombier 			oprange[AMULHWCC] = oprange[r];
546*fbadb1c4SDavid du Colombier 			oprange[AMULHWU] = oprange[r];
547*fbadb1c4SDavid du Colombier 			oprange[AMULHWUCC] = oprange[r];
548*fbadb1c4SDavid du Colombier 			oprange[AMULLWCC] = oprange[r];
549*fbadb1c4SDavid du Colombier 			oprange[AMULLWVCC] = oprange[r];
550*fbadb1c4SDavid du Colombier 			oprange[AMULLWV] = oprange[r];
551*fbadb1c4SDavid du Colombier 			oprange[ADIVWCC] = oprange[r];
552*fbadb1c4SDavid du Colombier 			oprange[ADIVWV] = oprange[r];
553*fbadb1c4SDavid du Colombier 			oprange[ADIVWVCC] = oprange[r];
554*fbadb1c4SDavid du Colombier 			oprange[ADIVWU] = oprange[r];
555*fbadb1c4SDavid du Colombier 			oprange[ADIVWUCC] = oprange[r];
556*fbadb1c4SDavid du Colombier 			oprange[ADIVWUV] = oprange[r];
557*fbadb1c4SDavid du Colombier 			oprange[ADIVWUVCC] = oprange[r];
558*fbadb1c4SDavid du Colombier 			oprange[AADDCC] = oprange[r];
559*fbadb1c4SDavid du Colombier 			oprange[AADDCV] = oprange[r];
560*fbadb1c4SDavid du Colombier 			oprange[AADDCVCC] = oprange[r];
561*fbadb1c4SDavid du Colombier 			oprange[AADDV] = oprange[r];
562*fbadb1c4SDavid du Colombier 			oprange[AADDVCC] = oprange[r];
563*fbadb1c4SDavid du Colombier 			oprange[AADDE] = oprange[r];
564*fbadb1c4SDavid du Colombier 			oprange[AADDECC] = oprange[r];
565*fbadb1c4SDavid du Colombier 			oprange[AADDEV] = oprange[r];
566*fbadb1c4SDavid du Colombier 			oprange[AADDEVCC] = oprange[r];
567*fbadb1c4SDavid du Colombier 			oprange[ACRAND] = oprange[r];
568*fbadb1c4SDavid du Colombier 			oprange[ACRANDN] = oprange[r];
569*fbadb1c4SDavid du Colombier 			oprange[ACREQV] = oprange[r];
570*fbadb1c4SDavid du Colombier 			oprange[ACRNAND] = oprange[r];
571*fbadb1c4SDavid du Colombier 			oprange[ACRNOR] = oprange[r];
572*fbadb1c4SDavid du Colombier 			oprange[ACROR] = oprange[r];
573*fbadb1c4SDavid du Colombier 			oprange[ACRORN] = oprange[r];
574*fbadb1c4SDavid du Colombier 			oprange[ACRXOR] = oprange[r];
575*fbadb1c4SDavid du Colombier 			oprange[AMULHD] = oprange[r];
576*fbadb1c4SDavid du Colombier 			oprange[AMULHDCC] = oprange[r];
577*fbadb1c4SDavid du Colombier 			oprange[AMULHDU] = oprange[r];
578*fbadb1c4SDavid du Colombier 			oprange[AMULHDUCC] = oprange[r];
579*fbadb1c4SDavid du Colombier 			oprange[AMULLD] = oprange[r];
580*fbadb1c4SDavid du Colombier 			oprange[AMULLDCC] = oprange[r];
581*fbadb1c4SDavid du Colombier 			oprange[AMULLDVCC] = oprange[r];
582*fbadb1c4SDavid du Colombier 			oprange[AMULLDV] = oprange[r];
583*fbadb1c4SDavid du Colombier 			oprange[ADIVD] = oprange[r];
584*fbadb1c4SDavid du Colombier 			oprange[ADIVDCC] = oprange[r];
585*fbadb1c4SDavid du Colombier 			oprange[ADIVDVCC] = oprange[r];
586*fbadb1c4SDavid du Colombier 			oprange[ADIVDV] = oprange[r];
587*fbadb1c4SDavid du Colombier 			oprange[ADIVDU] = oprange[r];
588*fbadb1c4SDavid du Colombier 			oprange[ADIVDUCC] = oprange[r];
589*fbadb1c4SDavid du Colombier 			oprange[ADIVDUVCC] = oprange[r];
590*fbadb1c4SDavid du Colombier 			oprange[ADIVDUCC] = oprange[r];
591*fbadb1c4SDavid du Colombier 			break;
592*fbadb1c4SDavid du Colombier 		case AMOVBZ:	/* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
593*fbadb1c4SDavid du Colombier 			oprange[AMOVH] = oprange[r];
594*fbadb1c4SDavid du Colombier 			oprange[AMOVHZ] = oprange[r];
595*fbadb1c4SDavid du Colombier 			break;
596*fbadb1c4SDavid du Colombier 		case AMOVBZU:	/* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
597*fbadb1c4SDavid du Colombier 			oprange[AMOVHU] = oprange[r];
598*fbadb1c4SDavid du Colombier 			oprange[AMOVHZU] = oprange[r];
599*fbadb1c4SDavid du Colombier 			oprange[AMOVWU] = oprange[r];
600*fbadb1c4SDavid du Colombier 			oprange[AMOVWZU] = oprange[r];
601*fbadb1c4SDavid du Colombier 			oprange[AMOVDU] = oprange[r];
602*fbadb1c4SDavid du Colombier 			oprange[AMOVMW] = oprange[r];
603*fbadb1c4SDavid du Colombier 			break;
604*fbadb1c4SDavid du Colombier 		case AAND:	/* logical op Rb,Rs,Ra; no literal */
605*fbadb1c4SDavid du Colombier 			oprange[AANDN] = oprange[r];
606*fbadb1c4SDavid du Colombier 			oprange[AANDNCC] = oprange[r];
607*fbadb1c4SDavid du Colombier 			oprange[AEQV] = oprange[r];
608*fbadb1c4SDavid du Colombier 			oprange[AEQVCC] = oprange[r];
609*fbadb1c4SDavid du Colombier 			oprange[ANAND] = oprange[r];
610*fbadb1c4SDavid du Colombier 			oprange[ANANDCC] = oprange[r];
611*fbadb1c4SDavid du Colombier 			oprange[ANOR] = oprange[r];
612*fbadb1c4SDavid du Colombier 			oprange[ANORCC] = oprange[r];
613*fbadb1c4SDavid du Colombier 			oprange[AORCC] = oprange[r];
614*fbadb1c4SDavid du Colombier 			oprange[AORN] = oprange[r];
615*fbadb1c4SDavid du Colombier 			oprange[AORNCC] = oprange[r];
616*fbadb1c4SDavid du Colombier 			oprange[AXORCC] = oprange[r];
617*fbadb1c4SDavid du Colombier 			break;
618*fbadb1c4SDavid du Colombier 		case AADDME:	/* op Ra, Rd */
619*fbadb1c4SDavid du Colombier 			oprange[AADDMECC] = oprange[r];
620*fbadb1c4SDavid du Colombier 			oprange[AADDMEV] = oprange[r];
621*fbadb1c4SDavid du Colombier 			oprange[AADDMEVCC] = oprange[r];
622*fbadb1c4SDavid du Colombier 			oprange[AADDZE] = oprange[r];
623*fbadb1c4SDavid du Colombier 			oprange[AADDZECC] = oprange[r];
624*fbadb1c4SDavid du Colombier 			oprange[AADDZEV] = oprange[r];
625*fbadb1c4SDavid du Colombier 			oprange[AADDZEVCC] = oprange[r];
626*fbadb1c4SDavid du Colombier 			oprange[ASUBME] = oprange[r];
627*fbadb1c4SDavid du Colombier 			oprange[ASUBMECC] = oprange[r];
628*fbadb1c4SDavid du Colombier 			oprange[ASUBMEV] = oprange[r];
629*fbadb1c4SDavid du Colombier 			oprange[ASUBMEVCC] = oprange[r];
630*fbadb1c4SDavid du Colombier 			oprange[ASUBZE] = oprange[r];
631*fbadb1c4SDavid du Colombier 			oprange[ASUBZECC] = oprange[r];
632*fbadb1c4SDavid du Colombier 			oprange[ASUBZEV] = oprange[r];
633*fbadb1c4SDavid du Colombier 			oprange[ASUBZEVCC] = oprange[r];
634*fbadb1c4SDavid du Colombier 			break;
635*fbadb1c4SDavid du Colombier 		case AADDC:
636*fbadb1c4SDavid du Colombier 			oprange[AADDCCC] = oprange[r];
637*fbadb1c4SDavid du Colombier 			break;
638*fbadb1c4SDavid du Colombier 		case ABEQ:
639*fbadb1c4SDavid du Colombier 			oprange[ABGE] = oprange[r];
640*fbadb1c4SDavid du Colombier 			oprange[ABGT] = oprange[r];
641*fbadb1c4SDavid du Colombier 			oprange[ABLE] = oprange[r];
642*fbadb1c4SDavid du Colombier 			oprange[ABLT] = oprange[r];
643*fbadb1c4SDavid du Colombier 			oprange[ABNE] = oprange[r];
644*fbadb1c4SDavid du Colombier 			oprange[ABVC] = oprange[r];
645*fbadb1c4SDavid du Colombier 			oprange[ABVS] = oprange[r];
646*fbadb1c4SDavid du Colombier 			break;
647*fbadb1c4SDavid du Colombier 		case ABR:
648*fbadb1c4SDavid du Colombier 			oprange[ABL] = oprange[r];
649*fbadb1c4SDavid du Colombier 			break;
650*fbadb1c4SDavid du Colombier 		case ABC:
651*fbadb1c4SDavid du Colombier 			oprange[ABCL] = oprange[r];
652*fbadb1c4SDavid du Colombier 			break;
653*fbadb1c4SDavid du Colombier 		case AEXTSB:	/* op Rs, Ra */
654*fbadb1c4SDavid du Colombier 			oprange[AEXTSBCC] = oprange[r];
655*fbadb1c4SDavid du Colombier 			oprange[AEXTSH] = oprange[r];
656*fbadb1c4SDavid du Colombier 			oprange[AEXTSHCC] = oprange[r];
657*fbadb1c4SDavid du Colombier 			oprange[ACNTLZW] = oprange[r];
658*fbadb1c4SDavid du Colombier 			oprange[ACNTLZWCC] = oprange[r];
659*fbadb1c4SDavid du Colombier 			oprange[ACNTLZD] = oprange[r];
660*fbadb1c4SDavid du Colombier 			oprange[AEXTSW] = oprange[r];
661*fbadb1c4SDavid du Colombier 			oprange[AEXTSWCC] = oprange[r];
662*fbadb1c4SDavid du Colombier 			oprange[ACNTLZDCC] = oprange[r];
663*fbadb1c4SDavid du Colombier 			break;
664*fbadb1c4SDavid du Colombier 		case AFABS:	/* fop [s,]d */
665*fbadb1c4SDavid du Colombier 			oprange[AFABSCC] = oprange[r];
666*fbadb1c4SDavid du Colombier 			oprange[AFNABS] = oprange[r];
667*fbadb1c4SDavid du Colombier 			oprange[AFNABSCC] = oprange[r];
668*fbadb1c4SDavid du Colombier 			oprange[AFNEG] = oprange[r];
669*fbadb1c4SDavid du Colombier 			oprange[AFNEGCC] = oprange[r];
670*fbadb1c4SDavid du Colombier 			oprange[AFRSP] = oprange[r];
671*fbadb1c4SDavid du Colombier 			oprange[AFRSPCC] = oprange[r];
672*fbadb1c4SDavid du Colombier 			oprange[AFCTIW] = oprange[r];
673*fbadb1c4SDavid du Colombier 			oprange[AFCTIWCC] = oprange[r];
674*fbadb1c4SDavid du Colombier 			oprange[AFCTIWZ] = oprange[r];
675*fbadb1c4SDavid du Colombier 			oprange[AFCTIWZCC] = oprange[r];
676*fbadb1c4SDavid du Colombier 			oprange[AFCTID] = oprange[r];
677*fbadb1c4SDavid du Colombier 			oprange[AFCTIDCC] = oprange[r];
678*fbadb1c4SDavid du Colombier 			oprange[AFCTIDZ] = oprange[r];
679*fbadb1c4SDavid du Colombier 			oprange[AFCTIDZCC] = oprange[r];
680*fbadb1c4SDavid du Colombier 			oprange[AFCFID] = oprange[r];
681*fbadb1c4SDavid du Colombier 			oprange[AFCFIDCC] = oprange[r];
682*fbadb1c4SDavid du Colombier 			oprange[AFRES] = oprange[r];
683*fbadb1c4SDavid du Colombier 			oprange[AFRESCC] = oprange[r];
684*fbadb1c4SDavid du Colombier 			oprange[AFRSQRTE] = oprange[r];
685*fbadb1c4SDavid du Colombier 			oprange[AFRSQRTECC] = oprange[r];
686*fbadb1c4SDavid du Colombier 			oprange[AFSQRT] = oprange[r];
687*fbadb1c4SDavid du Colombier 			oprange[AFSQRTCC] = oprange[r];
688*fbadb1c4SDavid du Colombier 			oprange[AFSQRTS] = oprange[r];
689*fbadb1c4SDavid du Colombier 			oprange[AFSQRTSCC] = oprange[r];
690*fbadb1c4SDavid du Colombier 			break;
691*fbadb1c4SDavid du Colombier 		case AFADD:
692*fbadb1c4SDavid du Colombier 			oprange[AFADDS] = oprange[r];
693*fbadb1c4SDavid du Colombier 			oprange[AFADDCC] = oprange[r];
694*fbadb1c4SDavid du Colombier 			oprange[AFADDSCC] = oprange[r];
695*fbadb1c4SDavid du Colombier 			oprange[AFDIV] = oprange[r];
696*fbadb1c4SDavid du Colombier 			oprange[AFDIVS] = oprange[r];
697*fbadb1c4SDavid du Colombier 			oprange[AFDIVCC] = oprange[r];
698*fbadb1c4SDavid du Colombier 			oprange[AFDIVSCC] = oprange[r];
699*fbadb1c4SDavid du Colombier 			oprange[AFSUB] = oprange[r];
700*fbadb1c4SDavid du Colombier 			oprange[AFSUBS] = oprange[r];
701*fbadb1c4SDavid du Colombier 			oprange[AFSUBCC] = oprange[r];
702*fbadb1c4SDavid du Colombier 			oprange[AFSUBSCC] = oprange[r];
703*fbadb1c4SDavid du Colombier 			break;
704*fbadb1c4SDavid du Colombier 		case AFMADD:
705*fbadb1c4SDavid du Colombier 			oprange[AFMADDCC] = oprange[r];
706*fbadb1c4SDavid du Colombier 			oprange[AFMADDS] = oprange[r];
707*fbadb1c4SDavid du Colombier 			oprange[AFMADDSCC] = oprange[r];
708*fbadb1c4SDavid du Colombier 			oprange[AFMSUB] = oprange[r];
709*fbadb1c4SDavid du Colombier 			oprange[AFMSUBCC] = oprange[r];
710*fbadb1c4SDavid du Colombier 			oprange[AFMSUBS] = oprange[r];
711*fbadb1c4SDavid du Colombier 			oprange[AFMSUBSCC] = oprange[r];
712*fbadb1c4SDavid du Colombier 			oprange[AFNMADD] = oprange[r];
713*fbadb1c4SDavid du Colombier 			oprange[AFNMADDCC] = oprange[r];
714*fbadb1c4SDavid du Colombier 			oprange[AFNMADDS] = oprange[r];
715*fbadb1c4SDavid du Colombier 			oprange[AFNMADDSCC] = oprange[r];
716*fbadb1c4SDavid du Colombier 			oprange[AFNMSUB] = oprange[r];
717*fbadb1c4SDavid du Colombier 			oprange[AFNMSUBCC] = oprange[r];
718*fbadb1c4SDavid du Colombier 			oprange[AFNMSUBS] = oprange[r];
719*fbadb1c4SDavid du Colombier 			oprange[AFNMSUBSCC] = oprange[r];
720*fbadb1c4SDavid du Colombier 			oprange[AFSEL] = oprange[r];
721*fbadb1c4SDavid du Colombier 			oprange[AFSELCC] = oprange[r];
722*fbadb1c4SDavid du Colombier 			break;
723*fbadb1c4SDavid du Colombier 		case AFMUL:
724*fbadb1c4SDavid du Colombier 			oprange[AFMULS] = oprange[r];
725*fbadb1c4SDavid du Colombier 			oprange[AFMULCC] = oprange[r];
726*fbadb1c4SDavid du Colombier 			oprange[AFMULSCC] = oprange[r];
727*fbadb1c4SDavid du Colombier 			break;
728*fbadb1c4SDavid du Colombier 		case AFCMPO:
729*fbadb1c4SDavid du Colombier 			oprange[AFCMPU] = oprange[r];
730*fbadb1c4SDavid du Colombier 			break;
731*fbadb1c4SDavid du Colombier 		case AMTFSB0:
732*fbadb1c4SDavid du Colombier 			oprange[AMTFSB0CC] = oprange[r];
733*fbadb1c4SDavid du Colombier 			oprange[AMTFSB1] = oprange[r];
734*fbadb1c4SDavid du Colombier 			oprange[AMTFSB1CC] = oprange[r];
735*fbadb1c4SDavid du Colombier 			break;
736*fbadb1c4SDavid du Colombier 		case ANEG:	/* op [Ra,] Rd */
737*fbadb1c4SDavid du Colombier 			oprange[ANEGCC] = oprange[r];
738*fbadb1c4SDavid du Colombier 			oprange[ANEGV] = oprange[r];
739*fbadb1c4SDavid du Colombier 			oprange[ANEGVCC] = oprange[r];
740*fbadb1c4SDavid du Colombier 			break;
741*fbadb1c4SDavid du Colombier 		case AOR:	/* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
742*fbadb1c4SDavid du Colombier 			oprange[AXOR] = oprange[r];
743*fbadb1c4SDavid du Colombier 			break;
744*fbadb1c4SDavid du Colombier 		case ASLW:
745*fbadb1c4SDavid du Colombier 			oprange[ASLWCC] = oprange[r];
746*fbadb1c4SDavid du Colombier 			oprange[ASRW] = oprange[r];
747*fbadb1c4SDavid du Colombier 			oprange[ASRWCC] = oprange[r];
748*fbadb1c4SDavid du Colombier 			break;
749*fbadb1c4SDavid du Colombier 		case ASLD:
750*fbadb1c4SDavid du Colombier 			oprange[ASLDCC] = oprange[r];
751*fbadb1c4SDavid du Colombier 			oprange[ASRD] = oprange[r];
752*fbadb1c4SDavid du Colombier 			oprange[ASRDCC] = oprange[r];
753*fbadb1c4SDavid du Colombier 			break;
754*fbadb1c4SDavid du Colombier 		case ASRAW:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
755*fbadb1c4SDavid du Colombier 			oprange[ASRAWCC] = oprange[r];
756*fbadb1c4SDavid du Colombier 			break;
757*fbadb1c4SDavid du Colombier 		case ASRAD:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
758*fbadb1c4SDavid du Colombier 			oprange[ASRADCC] = oprange[r];
759*fbadb1c4SDavid du Colombier 			break;
760*fbadb1c4SDavid du Colombier 		case ASUB:	/* SUB Ra,Rb,Rd => subf Rd,ra,rb */
761*fbadb1c4SDavid du Colombier 			oprange[ASUB] = oprange[r];
762*fbadb1c4SDavid du Colombier 			oprange[ASUBCC] = oprange[r];
763*fbadb1c4SDavid du Colombier 			oprange[ASUBV] = oprange[r];
764*fbadb1c4SDavid du Colombier 			oprange[ASUBVCC] = oprange[r];
765*fbadb1c4SDavid du Colombier 			oprange[ASUBCCC] = oprange[r];
766*fbadb1c4SDavid du Colombier 			oprange[ASUBCV] = oprange[r];
767*fbadb1c4SDavid du Colombier 			oprange[ASUBCVCC] = oprange[r];
768*fbadb1c4SDavid du Colombier 			oprange[ASUBE] = oprange[r];
769*fbadb1c4SDavid du Colombier 			oprange[ASUBECC] = oprange[r];
770*fbadb1c4SDavid du Colombier 			oprange[ASUBEV] = oprange[r];
771*fbadb1c4SDavid du Colombier 			oprange[ASUBEVCC] = oprange[r];
772*fbadb1c4SDavid du Colombier 			break;
773*fbadb1c4SDavid du Colombier 		case ASYNC:
774*fbadb1c4SDavid du Colombier 			oprange[AISYNC] = oprange[r];
775*fbadb1c4SDavid du Colombier 			oprange[APTESYNC] = oprange[r];
776*fbadb1c4SDavid du Colombier 			oprange[ATLBSYNC] = oprange[r];
777*fbadb1c4SDavid du Colombier 			break;
778*fbadb1c4SDavid du Colombier 		case ARLWMI:
779*fbadb1c4SDavid du Colombier 			oprange[ARLWMICC] = oprange[r];
780*fbadb1c4SDavid du Colombier 			oprange[ARLWNM] = oprange[r];
781*fbadb1c4SDavid du Colombier 			oprange[ARLWNMCC] = oprange[r];
782*fbadb1c4SDavid du Colombier 			break;
783*fbadb1c4SDavid du Colombier 		case ARLDMI:
784*fbadb1c4SDavid du Colombier 			oprange[ARLDMICC] = oprange[r];
785*fbadb1c4SDavid du Colombier 			break;
786*fbadb1c4SDavid du Colombier 		case ARLDC:
787*fbadb1c4SDavid du Colombier 			oprange[ARLDCCC] = oprange[r];
788*fbadb1c4SDavid du Colombier 			break;
789*fbadb1c4SDavid du Colombier 		case ARLDCL:
790*fbadb1c4SDavid du Colombier 			oprange[ARLDCR] = oprange[r];
791*fbadb1c4SDavid du Colombier 			oprange[ARLDCLCC] = oprange[r];
792*fbadb1c4SDavid du Colombier 			oprange[ARLDCRCC] = oprange[r];
793*fbadb1c4SDavid du Colombier 			break;
794*fbadb1c4SDavid du Colombier 		case AFMOVD:
795*fbadb1c4SDavid du Colombier 			oprange[AFMOVDCC] = oprange[r];
796*fbadb1c4SDavid du Colombier 			oprange[AFMOVDU] = oprange[r];
797*fbadb1c4SDavid du Colombier 			oprange[AFMOVS] = oprange[r];
798*fbadb1c4SDavid du Colombier 			oprange[AFMOVSU] = oprange[r];
799*fbadb1c4SDavid du Colombier 			break;
800*fbadb1c4SDavid du Colombier 		case AECIWX:
801*fbadb1c4SDavid du Colombier 			oprange[ALWAR] = oprange[r];
802*fbadb1c4SDavid du Colombier 			break;
803*fbadb1c4SDavid du Colombier 		case ASYSCALL:	/* just the op; flow of control */
804*fbadb1c4SDavid du Colombier 			oprange[ARFI] = oprange[r];
805*fbadb1c4SDavid du Colombier 			oprange[ARFCI] = oprange[r];
806*fbadb1c4SDavid du Colombier 			oprange[ARFID] = oprange[r];
807*fbadb1c4SDavid du Colombier 			oprange[AHRFID] = oprange[r];
808*fbadb1c4SDavid du Colombier 			break;
809*fbadb1c4SDavid du Colombier 		case AMOVHBR:
810*fbadb1c4SDavid du Colombier 			oprange[AMOVWBR] = oprange[r];
811*fbadb1c4SDavid du Colombier 			break;
812*fbadb1c4SDavid du Colombier 		case ASLBMFEE:
813*fbadb1c4SDavid du Colombier 			oprange[ASLBMFEV] = oprange[r];
814*fbadb1c4SDavid du Colombier 			break;
815*fbadb1c4SDavid du Colombier 		case ATW:
816*fbadb1c4SDavid du Colombier 			oprange[ATD] = oprange[r];
817*fbadb1c4SDavid du Colombier 			break;
818*fbadb1c4SDavid du Colombier 		case ATLBIE:
819*fbadb1c4SDavid du Colombier 			oprange[ASLBIE] = oprange[r];
820*fbadb1c4SDavid du Colombier 			oprange[ATLBIEL] = oprange[r];
821*fbadb1c4SDavid du Colombier 			break;
822*fbadb1c4SDavid du Colombier 		case AEIEIO:
823*fbadb1c4SDavid du Colombier 			oprange[ASLBIA] = oprange[r];
824*fbadb1c4SDavid du Colombier 			break;
825*fbadb1c4SDavid du Colombier 		case ACMP:
826*fbadb1c4SDavid du Colombier 			oprange[ACMPW] = oprange[r];
827*fbadb1c4SDavid du Colombier 			break;
828*fbadb1c4SDavid du Colombier 		case ACMPU:
829*fbadb1c4SDavid du Colombier 			oprange[ACMPWU] = oprange[r];
830*fbadb1c4SDavid du Colombier 			break;
831*fbadb1c4SDavid du Colombier 		case AADD:
832*fbadb1c4SDavid du Colombier 		case AANDCC:	/* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
833*fbadb1c4SDavid du Colombier 		case ALSW:
834*fbadb1c4SDavid du Colombier 		case AMOVW:	/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
835*fbadb1c4SDavid du Colombier 		case AMOVWZ:	/* load/store/move word with zero extension; move 32-bit literals  */
836*fbadb1c4SDavid du Colombier 		case AMOVD:	/* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
837*fbadb1c4SDavid du Colombier 		case AMOVB:	/* macro: move byte with sign extension */
838*fbadb1c4SDavid du Colombier 		case AMOVBU:	/* macro: move byte with sign extension & update */
839*fbadb1c4SDavid du Colombier 		case AMOVFL:
840*fbadb1c4SDavid du Colombier 		case AMULLW:	/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
841*fbadb1c4SDavid du Colombier 		case ASUBC:	/* op r1,$s,r3; op r1[,r2],r3 */
842*fbadb1c4SDavid du Colombier 		case ASTSW:
843*fbadb1c4SDavid du Colombier 		case ASLBMTE:
844*fbadb1c4SDavid du Colombier 		case AWORD:
845*fbadb1c4SDavid du Colombier 		case ADWORD:
846*fbadb1c4SDavid du Colombier 		case ANOP:
847*fbadb1c4SDavid du Colombier 		case ATEXT:
848*fbadb1c4SDavid du Colombier 			break;
849*fbadb1c4SDavid du Colombier 		}
850*fbadb1c4SDavid du Colombier 	}
851*fbadb1c4SDavid du Colombier }
852*fbadb1c4SDavid du Colombier 
853*fbadb1c4SDavid du Colombier enum{
854*fbadb1c4SDavid du Colombier 	ABSD = 0,
855*fbadb1c4SDavid du Colombier 	ABSU = 1,
856*fbadb1c4SDavid du Colombier 	RELD = 2,
857*fbadb1c4SDavid du Colombier 	RELU = 3,
858*fbadb1c4SDavid du Colombier };
859*fbadb1c4SDavid du Colombier 
860*fbadb1c4SDavid du Colombier int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
861*fbadb1c4SDavid du Colombier 
862*fbadb1c4SDavid du Colombier typedef struct Reloc Reloc;
863*fbadb1c4SDavid du Colombier 
864*fbadb1c4SDavid du Colombier struct Reloc
865*fbadb1c4SDavid du Colombier {
866*fbadb1c4SDavid du Colombier 	int n;
867*fbadb1c4SDavid du Colombier 	int t;
868*fbadb1c4SDavid du Colombier 	uchar *m;
869*fbadb1c4SDavid du Colombier 	ulong *a;
870*fbadb1c4SDavid du Colombier };
871*fbadb1c4SDavid du Colombier 
872*fbadb1c4SDavid du Colombier Reloc rels;
873*fbadb1c4SDavid du Colombier 
874*fbadb1c4SDavid du Colombier static void
grow(Reloc * r)875*fbadb1c4SDavid du Colombier grow(Reloc *r)
876*fbadb1c4SDavid du Colombier {
877*fbadb1c4SDavid du Colombier 	int t;
878*fbadb1c4SDavid du Colombier 	uchar *m, *nm;
879*fbadb1c4SDavid du Colombier 	ulong *a, *na;
880*fbadb1c4SDavid du Colombier 
881*fbadb1c4SDavid du Colombier 	t = r->t;
882*fbadb1c4SDavid du Colombier 	r->t += 64;
883*fbadb1c4SDavid du Colombier 	m = r->m;
884*fbadb1c4SDavid du Colombier 	a = r->a;
885*fbadb1c4SDavid du Colombier 	r->m = nm = malloc(r->t*sizeof(uchar));
886*fbadb1c4SDavid du Colombier 	r->a = na = malloc(r->t*sizeof(ulong));
887*fbadb1c4SDavid du Colombier 	memmove(nm, m, t*sizeof(uchar));
888*fbadb1c4SDavid du Colombier 	memmove(na, a, t*sizeof(ulong));
889*fbadb1c4SDavid du Colombier 	free(m);
890*fbadb1c4SDavid du Colombier 	free(a);
891*fbadb1c4SDavid du Colombier }
892*fbadb1c4SDavid du Colombier 
893*fbadb1c4SDavid du Colombier void
dynreloc(Sym * s,long v,int abs,int split,int sext)894*fbadb1c4SDavid du Colombier dynreloc(Sym *s, long v, int abs, int split, int sext)
895*fbadb1c4SDavid du Colombier {
896*fbadb1c4SDavid du Colombier 	int i, k, n;
897*fbadb1c4SDavid du Colombier 	uchar *m;
898*fbadb1c4SDavid du Colombier 	ulong *a;
899*fbadb1c4SDavid du Colombier 	Reloc *r;
900*fbadb1c4SDavid du Colombier 
901*fbadb1c4SDavid du Colombier 	if(v&3)
902*fbadb1c4SDavid du Colombier 		diag("bad relocation address");
903*fbadb1c4SDavid du Colombier 	v >>= 2;
904*fbadb1c4SDavid du Colombier 	if(s->type == SUNDEF)
905*fbadb1c4SDavid du Colombier 		k = abs ? ABSU : RELU;
906*fbadb1c4SDavid du Colombier 	else
907*fbadb1c4SDavid du Colombier 		k = abs ? ABSD : RELD;
908*fbadb1c4SDavid du Colombier 	if(split)
909*fbadb1c4SDavid du Colombier 		k += 4;
910*fbadb1c4SDavid du Colombier 	if(sext)
911*fbadb1c4SDavid du Colombier 		k += 2;
912*fbadb1c4SDavid du Colombier 	/* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
913*fbadb1c4SDavid du Colombier 	k = modemap[k];
914*fbadb1c4SDavid du Colombier 	r = &rels;
915*fbadb1c4SDavid du Colombier 	n = r->n;
916*fbadb1c4SDavid du Colombier 	if(n >= r->t)
917*fbadb1c4SDavid du Colombier 		grow(r);
918*fbadb1c4SDavid du Colombier 	m = r->m;
919*fbadb1c4SDavid du Colombier 	a = r->a;
920*fbadb1c4SDavid du Colombier 	for(i = n; i > 0; i--){
921*fbadb1c4SDavid du Colombier 		if(v < a[i-1]){	/* happens occasionally for data */
922*fbadb1c4SDavid du Colombier 			m[i] = m[i-1];
923*fbadb1c4SDavid du Colombier 			a[i] = a[i-1];
924*fbadb1c4SDavid du Colombier 		}
925*fbadb1c4SDavid du Colombier 		else
926*fbadb1c4SDavid du Colombier 			break;
927*fbadb1c4SDavid du Colombier 	}
928*fbadb1c4SDavid du Colombier 	m[i] = k;
929*fbadb1c4SDavid du Colombier 	a[i] = v;
930*fbadb1c4SDavid du Colombier 	r->n++;
931*fbadb1c4SDavid du Colombier }
932*fbadb1c4SDavid du Colombier 
933*fbadb1c4SDavid du Colombier static int
sput(char * s)934*fbadb1c4SDavid du Colombier sput(char *s)
935*fbadb1c4SDavid du Colombier {
936*fbadb1c4SDavid du Colombier 	char *p;
937*fbadb1c4SDavid du Colombier 
938*fbadb1c4SDavid du Colombier 	p = s;
939*fbadb1c4SDavid du Colombier 	while(*s)
940*fbadb1c4SDavid du Colombier 		cput(*s++);
941*fbadb1c4SDavid du Colombier 	cput(0);
942*fbadb1c4SDavid du Colombier 	return s-p+1;
943*fbadb1c4SDavid du Colombier }
944*fbadb1c4SDavid du Colombier 
945*fbadb1c4SDavid du Colombier void
asmdyn()946*fbadb1c4SDavid du Colombier asmdyn()
947*fbadb1c4SDavid du Colombier {
948*fbadb1c4SDavid du Colombier 	int i, n, t, c;
949*fbadb1c4SDavid du Colombier 	Sym *s;
950*fbadb1c4SDavid du Colombier 	ulong la, ra, *a;
951*fbadb1c4SDavid du Colombier 	vlong off;
952*fbadb1c4SDavid du Colombier 	uchar *m;
953*fbadb1c4SDavid du Colombier 	Reloc *r;
954*fbadb1c4SDavid du Colombier 
955*fbadb1c4SDavid du Colombier 	cflush();
956*fbadb1c4SDavid du Colombier 	off = seek(cout, 0, 1);
957*fbadb1c4SDavid du Colombier 	lput(0);
958*fbadb1c4SDavid du Colombier 	t = 0;
959*fbadb1c4SDavid du Colombier 	lput(imports);
960*fbadb1c4SDavid du Colombier 	t += 4;
961*fbadb1c4SDavid du Colombier 	for(i = 0; i < NHASH; i++)
962*fbadb1c4SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
963*fbadb1c4SDavid du Colombier 			if(s->type == SUNDEF){
964*fbadb1c4SDavid du Colombier 				lput(s->sig);
965*fbadb1c4SDavid du Colombier 				t += 4;
966*fbadb1c4SDavid du Colombier 				t += sput(s->name);
967*fbadb1c4SDavid du Colombier 			}
968*fbadb1c4SDavid du Colombier 
969*fbadb1c4SDavid du Colombier 	la = 0;
970*fbadb1c4SDavid du Colombier 	r = &rels;
971*fbadb1c4SDavid du Colombier 	n = r->n;
972*fbadb1c4SDavid du Colombier 	m = r->m;
973*fbadb1c4SDavid du Colombier 	a = r->a;
974*fbadb1c4SDavid du Colombier 	lput(n);
975*fbadb1c4SDavid du Colombier 	t += 4;
976*fbadb1c4SDavid du Colombier 	for(i = 0; i < n; i++){
977*fbadb1c4SDavid du Colombier 		ra = *a-la;
978*fbadb1c4SDavid du Colombier 		if(*a < la)
979*fbadb1c4SDavid du Colombier 			diag("bad relocation order");
980*fbadb1c4SDavid du Colombier 		if(ra < 256)
981*fbadb1c4SDavid du Colombier 			c = 0;
982*fbadb1c4SDavid du Colombier 		else if(ra < 65536)
983*fbadb1c4SDavid du Colombier 			c = 1;
984*fbadb1c4SDavid du Colombier 		else
985*fbadb1c4SDavid du Colombier 			c = 2;
986*fbadb1c4SDavid du Colombier 		cput((c<<6)|*m++);
987*fbadb1c4SDavid du Colombier 		t++;
988*fbadb1c4SDavid du Colombier 		if(c == 0){
989*fbadb1c4SDavid du Colombier 			cput(ra);
990*fbadb1c4SDavid du Colombier 			t++;
991*fbadb1c4SDavid du Colombier 		}
992*fbadb1c4SDavid du Colombier 		else if(c == 1){
993*fbadb1c4SDavid du Colombier 			wput(ra);
994*fbadb1c4SDavid du Colombier 			t += 2;
995*fbadb1c4SDavid du Colombier 		}
996*fbadb1c4SDavid du Colombier 		else{
997*fbadb1c4SDavid du Colombier 			lput(ra);
998*fbadb1c4SDavid du Colombier 			t += 4;
999*fbadb1c4SDavid du Colombier 		}
1000*fbadb1c4SDavid du Colombier 		la = *a++;
1001*fbadb1c4SDavid du Colombier 	}
1002*fbadb1c4SDavid du Colombier 
1003*fbadb1c4SDavid du Colombier 	cflush();
1004*fbadb1c4SDavid du Colombier 	seek(cout, off, 0);
1005*fbadb1c4SDavid du Colombier 	lput(t);
1006*fbadb1c4SDavid du Colombier 
1007*fbadb1c4SDavid du Colombier 	if(debug['v']){
1008*fbadb1c4SDavid du Colombier 		Bprint(&bso, "import table entries = %d\n", imports);
1009*fbadb1c4SDavid du Colombier 		Bprint(&bso, "export table entries = %d\n", exports);
1010*fbadb1c4SDavid du Colombier 	}
1011*fbadb1c4SDavid du Colombier }
1012