xref: /plan9/sys/src/cmd/6l/pass.c (revision e887ea33cf0b0f75911958e2324340660b13e9eb)
1*e887ea33SDavid du Colombier #include	"l.h"
2*e887ea33SDavid du Colombier 
3*e887ea33SDavid du Colombier void
dodata(void)4*e887ea33SDavid du Colombier dodata(void)
5*e887ea33SDavid du Colombier {
6*e887ea33SDavid du Colombier 	int i;
7*e887ea33SDavid du Colombier 	Sym *s;
8*e887ea33SDavid du Colombier 	Prog *p;
9*e887ea33SDavid du Colombier 	long t, u;
10*e887ea33SDavid du Colombier 
11*e887ea33SDavid du Colombier 	if(debug['v'])
12*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f dodata\n", cputime());
13*e887ea33SDavid du Colombier 	Bflush(&bso);
14*e887ea33SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
15*e887ea33SDavid du Colombier 		s = p->from.sym;
16*e887ea33SDavid du Colombier 		if(p->as == ADYNT || p->as == AINIT)
17*e887ea33SDavid du Colombier 			s->value = dtype;
18*e887ea33SDavid du Colombier 		if(s->type == SBSS)
19*e887ea33SDavid du Colombier 			s->type = SDATA;
20*e887ea33SDavid du Colombier 		if(s->type != SDATA)
21*e887ea33SDavid du Colombier 			diag("initialize non-data (%d): %s\n%P",
22*e887ea33SDavid du Colombier 				s->type, s->name, p);
23*e887ea33SDavid du Colombier 		t = p->from.offset + p->width;
24*e887ea33SDavid du Colombier 		if(t > s->value)
25*e887ea33SDavid du Colombier 			diag("initialize bounds (%lld): %s\n%P",
26*e887ea33SDavid du Colombier 				s->value, s->name, p);
27*e887ea33SDavid du Colombier 	}
28*e887ea33SDavid du Colombier 	/* allocate small guys */
29*e887ea33SDavid du Colombier 	datsize = 0;
30*e887ea33SDavid du Colombier 	for(i=0; i<NHASH; i++)
31*e887ea33SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link) {
32*e887ea33SDavid du Colombier 		if(s->type != SDATA)
33*e887ea33SDavid du Colombier 		if(s->type != SBSS)
34*e887ea33SDavid du Colombier 			continue;
35*e887ea33SDavid du Colombier 		t = s->value;
36*e887ea33SDavid du Colombier 		if(t == 0) {
37*e887ea33SDavid du Colombier 			diag("%s: no size", s->name);
38*e887ea33SDavid du Colombier 			t = 1;
39*e887ea33SDavid du Colombier 		}
40*e887ea33SDavid du Colombier 		t = rnd(t, 4);
41*e887ea33SDavid du Colombier 		s->value = t;
42*e887ea33SDavid du Colombier 		if(t > MINSIZ)
43*e887ea33SDavid du Colombier 			continue;
44*e887ea33SDavid du Colombier 		if(t >= 8)
45*e887ea33SDavid du Colombier 			datsize = rnd(datsize, 8);
46*e887ea33SDavid du Colombier 		s->value = datsize;
47*e887ea33SDavid du Colombier 		datsize += t;
48*e887ea33SDavid du Colombier 		s->type = SDATA1;
49*e887ea33SDavid du Colombier 	}
50*e887ea33SDavid du Colombier 
51*e887ea33SDavid du Colombier 	/* allocate the rest of the data */
52*e887ea33SDavid du Colombier 	for(i=0; i<NHASH; i++)
53*e887ea33SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link) {
54*e887ea33SDavid du Colombier 		if(s->type != SDATA) {
55*e887ea33SDavid du Colombier 			if(s->type == SDATA1)
56*e887ea33SDavid du Colombier 				s->type = SDATA;
57*e887ea33SDavid du Colombier 			continue;
58*e887ea33SDavid du Colombier 		}
59*e887ea33SDavid du Colombier 		t = s->value;
60*e887ea33SDavid du Colombier 		if(t >= 8)
61*e887ea33SDavid du Colombier 			datsize = rnd(datsize, 8);
62*e887ea33SDavid du Colombier 		s->value = datsize;
63*e887ea33SDavid du Colombier 		datsize += t;
64*e887ea33SDavid du Colombier 	}
65*e887ea33SDavid du Colombier 	if(datsize)
66*e887ea33SDavid du Colombier 		datsize = rnd(datsize, 8);
67*e887ea33SDavid du Colombier 
68*e887ea33SDavid du Colombier 	if(debug['j']) {
69*e887ea33SDavid du Colombier 		/*
70*e887ea33SDavid du Colombier 		 * pad data with bss that fits up to next
71*e887ea33SDavid du Colombier 		 * 8k boundary, then push data to 8k
72*e887ea33SDavid du Colombier 		 */
73*e887ea33SDavid du Colombier 		u = rnd(datsize, 8192);
74*e887ea33SDavid du Colombier 		u -= datsize;
75*e887ea33SDavid du Colombier 		for(i=0; i<NHASH; i++)
76*e887ea33SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link) {
77*e887ea33SDavid du Colombier 			if(s->type != SBSS)
78*e887ea33SDavid du Colombier 				continue;
79*e887ea33SDavid du Colombier 			t = s->value;
80*e887ea33SDavid du Colombier 			if(t > u)
81*e887ea33SDavid du Colombier 				continue;
82*e887ea33SDavid du Colombier 			u -= t;
83*e887ea33SDavid du Colombier 			s->value = datsize;
84*e887ea33SDavid du Colombier 			s->type = SDATA;
85*e887ea33SDavid du Colombier 			datsize += t;
86*e887ea33SDavid du Colombier 		}
87*e887ea33SDavid du Colombier 		datsize += u;
88*e887ea33SDavid du Colombier 	}
89*e887ea33SDavid du Colombier 
90*e887ea33SDavid du Colombier 	/* now the bss */
91*e887ea33SDavid du Colombier 	bsssize = 0;
92*e887ea33SDavid du Colombier 	for(i=0; i<NHASH; i++)
93*e887ea33SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link) {
94*e887ea33SDavid du Colombier 		if(s->type != SBSS)
95*e887ea33SDavid du Colombier 			continue;
96*e887ea33SDavid du Colombier 		t = s->value;
97*e887ea33SDavid du Colombier 		if(t >= 8)
98*e887ea33SDavid du Colombier 			bsssize = rnd(bsssize, 8);
99*e887ea33SDavid du Colombier 		s->value = bsssize + datsize;
100*e887ea33SDavid du Colombier 		bsssize += t;
101*e887ea33SDavid du Colombier 	}
102*e887ea33SDavid du Colombier 	xdefine("edata", SBSS, datsize);
103*e887ea33SDavid du Colombier 	xdefine("end", SBSS, bsssize + datsize);
104*e887ea33SDavid du Colombier }
105*e887ea33SDavid du Colombier 
106*e887ea33SDavid du Colombier Prog*
brchain(Prog * p)107*e887ea33SDavid du Colombier brchain(Prog *p)
108*e887ea33SDavid du Colombier {
109*e887ea33SDavid du Colombier 	int i;
110*e887ea33SDavid du Colombier 
111*e887ea33SDavid du Colombier 	for(i=0; i<20; i++) {
112*e887ea33SDavid du Colombier 		if(p == P || p->as != AJMP)
113*e887ea33SDavid du Colombier 			return p;
114*e887ea33SDavid du Colombier 		p = p->pcond;
115*e887ea33SDavid du Colombier 	}
116*e887ea33SDavid du Colombier 	return P;
117*e887ea33SDavid du Colombier }
118*e887ea33SDavid du Colombier 
119*e887ea33SDavid du Colombier void
follow(void)120*e887ea33SDavid du Colombier follow(void)
121*e887ea33SDavid du Colombier {
122*e887ea33SDavid du Colombier 
123*e887ea33SDavid du Colombier 	if(debug['v'])
124*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f follow\n", cputime());
125*e887ea33SDavid du Colombier 	Bflush(&bso);
126*e887ea33SDavid du Colombier 	firstp = prg();
127*e887ea33SDavid du Colombier 	lastp = firstp;
128*e887ea33SDavid du Colombier 	xfol(textp);
129*e887ea33SDavid du Colombier 	lastp->link = P;
130*e887ea33SDavid du Colombier 	firstp = firstp->link;
131*e887ea33SDavid du Colombier }
132*e887ea33SDavid du Colombier 
133*e887ea33SDavid du Colombier void
xfol(Prog * p)134*e887ea33SDavid du Colombier xfol(Prog *p)
135*e887ea33SDavid du Colombier {
136*e887ea33SDavid du Colombier 	Prog *q;
137*e887ea33SDavid du Colombier 	int i;
138*e887ea33SDavid du Colombier 	enum as a;
139*e887ea33SDavid du Colombier 
140*e887ea33SDavid du Colombier loop:
141*e887ea33SDavid du Colombier 	if(p == P)
142*e887ea33SDavid du Colombier 		return;
143*e887ea33SDavid du Colombier 	if(p->as == ATEXT)
144*e887ea33SDavid du Colombier 		curtext = p;
145*e887ea33SDavid du Colombier 	if(p->as == AJMP)
146*e887ea33SDavid du Colombier 	if((q = p->pcond) != P) {
147*e887ea33SDavid du Colombier 		p->mark = 1;
148*e887ea33SDavid du Colombier 		p = q;
149*e887ea33SDavid du Colombier 		if(p->mark == 0)
150*e887ea33SDavid du Colombier 			goto loop;
151*e887ea33SDavid du Colombier 	}
152*e887ea33SDavid du Colombier 	if(p->mark) {
153*e887ea33SDavid du Colombier 		/* copy up to 4 instructions to avoid branch */
154*e887ea33SDavid du Colombier 		for(i=0,q=p; i<4; i++,q=q->link) {
155*e887ea33SDavid du Colombier 			if(q == P)
156*e887ea33SDavid du Colombier 				break;
157*e887ea33SDavid du Colombier 			if(q == lastp)
158*e887ea33SDavid du Colombier 				break;
159*e887ea33SDavid du Colombier 			a = q->as;
160*e887ea33SDavid du Colombier 			if(a == ANOP) {
161*e887ea33SDavid du Colombier 				i--;
162*e887ea33SDavid du Colombier 				continue;
163*e887ea33SDavid du Colombier 			}
164*e887ea33SDavid du Colombier 			switch(a) {
165*e887ea33SDavid du Colombier 			case AJMP:
166*e887ea33SDavid du Colombier 			case ARET:
167*e887ea33SDavid du Colombier 			case AIRETL:
168*e887ea33SDavid du Colombier 			case AIRETQ:
169*e887ea33SDavid du Colombier 			case AIRETW:
170*e887ea33SDavid du Colombier 			case ARETFL:
171*e887ea33SDavid du Colombier 			case ARETFQ:
172*e887ea33SDavid du Colombier 			case ARETFW:
173*e887ea33SDavid du Colombier 
174*e887ea33SDavid du Colombier 			case APUSHL:
175*e887ea33SDavid du Colombier 			case APUSHFL:
176*e887ea33SDavid du Colombier 			case APUSHQ:
177*e887ea33SDavid du Colombier 			case APUSHFQ:
178*e887ea33SDavid du Colombier 			case APUSHW:
179*e887ea33SDavid du Colombier 			case APUSHFW:
180*e887ea33SDavid du Colombier 			case APOPL:
181*e887ea33SDavid du Colombier 			case APOPFL:
182*e887ea33SDavid du Colombier 			case APOPQ:
183*e887ea33SDavid du Colombier 			case APOPFQ:
184*e887ea33SDavid du Colombier 			case APOPW:
185*e887ea33SDavid du Colombier 			case APOPFW:
186*e887ea33SDavid du Colombier 				goto brk;
187*e887ea33SDavid du Colombier 			}
188*e887ea33SDavid du Colombier 			if(q->pcond == P || q->pcond->mark)
189*e887ea33SDavid du Colombier 				continue;
190*e887ea33SDavid du Colombier 			if(a == ACALL || a == ALOOP)
191*e887ea33SDavid du Colombier 				continue;
192*e887ea33SDavid du Colombier 			for(;;) {
193*e887ea33SDavid du Colombier 				if(p->as == ANOP) {
194*e887ea33SDavid du Colombier 					p = p->link;
195*e887ea33SDavid du Colombier 					continue;
196*e887ea33SDavid du Colombier 				}
197*e887ea33SDavid du Colombier 				q = copyp(p);
198*e887ea33SDavid du Colombier 				p = p->link;
199*e887ea33SDavid du Colombier 				q->mark = 1;
200*e887ea33SDavid du Colombier 				lastp->link = q;
201*e887ea33SDavid du Colombier 				lastp = q;
202*e887ea33SDavid du Colombier 				if(q->as != a || q->pcond == P || q->pcond->mark)
203*e887ea33SDavid du Colombier 					continue;
204*e887ea33SDavid du Colombier 
205*e887ea33SDavid du Colombier 				q->as = relinv(q->as);
206*e887ea33SDavid du Colombier 				p = q->pcond;
207*e887ea33SDavid du Colombier 				q->pcond = q->link;
208*e887ea33SDavid du Colombier 				q->link = p;
209*e887ea33SDavid du Colombier 				xfol(q->link);
210*e887ea33SDavid du Colombier 				p = q->link;
211*e887ea33SDavid du Colombier 				if(p->mark)
212*e887ea33SDavid du Colombier 					return;
213*e887ea33SDavid du Colombier 				goto loop;
214*e887ea33SDavid du Colombier 			}
215*e887ea33SDavid du Colombier 		} /* */
216*e887ea33SDavid du Colombier 	brk:;
217*e887ea33SDavid du Colombier 		q = prg();
218*e887ea33SDavid du Colombier 		q->as = AJMP;
219*e887ea33SDavid du Colombier 		q->line = p->line;
220*e887ea33SDavid du Colombier 		q->to.type = D_BRANCH;
221*e887ea33SDavid du Colombier 		q->to.offset = p->pc;
222*e887ea33SDavid du Colombier 		q->pcond = p;
223*e887ea33SDavid du Colombier 		p = q;
224*e887ea33SDavid du Colombier 	}
225*e887ea33SDavid du Colombier 	p->mark = 1;
226*e887ea33SDavid du Colombier 	lastp->link = p;
227*e887ea33SDavid du Colombier 	lastp = p;
228*e887ea33SDavid du Colombier 	a = p->as;
229*e887ea33SDavid du Colombier 	if(a == AJMP || a == ARET || a == AIRETL || a == AIRETQ || a == AIRETW ||
230*e887ea33SDavid du Colombier 	   a == ARETFL || a == ARETFQ || a == ARETFW)
231*e887ea33SDavid du Colombier 		return;
232*e887ea33SDavid du Colombier 	if(p->pcond != P)
233*e887ea33SDavid du Colombier 	if(a != ACALL) {
234*e887ea33SDavid du Colombier 		q = brchain(p->link);
235*e887ea33SDavid du Colombier 		if(q != P && q->mark)
236*e887ea33SDavid du Colombier 		if(a != ALOOP) {
237*e887ea33SDavid du Colombier 			p->as = relinv(a);
238*e887ea33SDavid du Colombier 			p->link = p->pcond;
239*e887ea33SDavid du Colombier 			p->pcond = q;
240*e887ea33SDavid du Colombier 		}
241*e887ea33SDavid du Colombier 		xfol(p->link);
242*e887ea33SDavid du Colombier 		q = brchain(p->pcond);
243*e887ea33SDavid du Colombier 		if(q->mark) {
244*e887ea33SDavid du Colombier 			p->pcond = q;
245*e887ea33SDavid du Colombier 			return;
246*e887ea33SDavid du Colombier 		}
247*e887ea33SDavid du Colombier 		p = q;
248*e887ea33SDavid du Colombier 		goto loop;
249*e887ea33SDavid du Colombier 	}
250*e887ea33SDavid du Colombier 	p = p->link;
251*e887ea33SDavid du Colombier 	goto loop;
252*e887ea33SDavid du Colombier }
253*e887ea33SDavid du Colombier 
254*e887ea33SDavid du Colombier int
relinv(int a)255*e887ea33SDavid du Colombier relinv(int a)
256*e887ea33SDavid du Colombier {
257*e887ea33SDavid du Colombier 
258*e887ea33SDavid du Colombier 	switch(a) {
259*e887ea33SDavid du Colombier 	case AJEQ:	return AJNE;
260*e887ea33SDavid du Colombier 	case AJNE:	return AJEQ;
261*e887ea33SDavid du Colombier 	case AJLE:	return AJGT;
262*e887ea33SDavid du Colombier 	case AJLS:	return AJHI;
263*e887ea33SDavid du Colombier 	case AJLT:	return AJGE;
264*e887ea33SDavid du Colombier 	case AJMI:	return AJPL;
265*e887ea33SDavid du Colombier 	case AJGE:	return AJLT;
266*e887ea33SDavid du Colombier 	case AJPL:	return AJMI;
267*e887ea33SDavid du Colombier 	case AJGT:	return AJLE;
268*e887ea33SDavid du Colombier 	case AJHI:	return AJLS;
269*e887ea33SDavid du Colombier 	case AJCS:	return AJCC;
270*e887ea33SDavid du Colombier 	case AJCC:	return AJCS;
271*e887ea33SDavid du Colombier 	case AJPS:	return AJPC;
272*e887ea33SDavid du Colombier 	case AJPC:	return AJPS;
273*e887ea33SDavid du Colombier 	case AJOS:	return AJOC;
274*e887ea33SDavid du Colombier 	case AJOC:	return AJOS;
275*e887ea33SDavid du Colombier 	}
276*e887ea33SDavid du Colombier 	diag("unknown relation: %s in %s", anames[a], TNAME);
277*e887ea33SDavid du Colombier 	return a;
278*e887ea33SDavid du Colombier }
279*e887ea33SDavid du Colombier 
280*e887ea33SDavid du Colombier void
doinit(void)281*e887ea33SDavid du Colombier doinit(void)
282*e887ea33SDavid du Colombier {
283*e887ea33SDavid du Colombier 	Sym *s;
284*e887ea33SDavid du Colombier 	Prog *p;
285*e887ea33SDavid du Colombier 	int x;
286*e887ea33SDavid du Colombier 
287*e887ea33SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
288*e887ea33SDavid du Colombier 		x = p->to.type;
289*e887ea33SDavid du Colombier 		if(x != D_EXTERN && x != D_STATIC)
290*e887ea33SDavid du Colombier 			continue;
291*e887ea33SDavid du Colombier 		s = p->to.sym;
292*e887ea33SDavid du Colombier 		if(s->type == 0 || s->type == SXREF)
293*e887ea33SDavid du Colombier 			diag("undefined %s initializer of %s",
294*e887ea33SDavid du Colombier 				s->name, p->from.sym->name);
295*e887ea33SDavid du Colombier 		p->to.offset += s->value;
296*e887ea33SDavid du Colombier 		p->to.type = D_CONST;
297*e887ea33SDavid du Colombier 		if(s->type == SDATA || s->type == SBSS)
298*e887ea33SDavid du Colombier 			p->to.offset += INITDAT;
299*e887ea33SDavid du Colombier 	}
300*e887ea33SDavid du Colombier }
301*e887ea33SDavid du Colombier 
302*e887ea33SDavid du Colombier void
patch(void)303*e887ea33SDavid du Colombier patch(void)
304*e887ea33SDavid du Colombier {
305*e887ea33SDavid du Colombier 	long c;
306*e887ea33SDavid du Colombier 	Prog *p, *q;
307*e887ea33SDavid du Colombier 	Sym *s;
308*e887ea33SDavid du Colombier 	long vexit;
309*e887ea33SDavid du Colombier 
310*e887ea33SDavid du Colombier 	if(debug['v'])
311*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f mkfwd\n", cputime());
312*e887ea33SDavid du Colombier 	Bflush(&bso);
313*e887ea33SDavid du Colombier 	mkfwd();
314*e887ea33SDavid du Colombier 	if(debug['v'])
315*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f patch\n", cputime());
316*e887ea33SDavid du Colombier 	Bflush(&bso);
317*e887ea33SDavid du Colombier 	s = lookup("exit", 0);
318*e887ea33SDavid du Colombier 	vexit = s->value;
319*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
320*e887ea33SDavid du Colombier 		if(p->as == ATEXT)
321*e887ea33SDavid du Colombier 			curtext = p;
322*e887ea33SDavid du Colombier 		if(p->as == ACALL || p->as == ARET) {
323*e887ea33SDavid du Colombier 			s = p->to.sym;
324*e887ea33SDavid du Colombier 			if(s) {
325*e887ea33SDavid du Colombier 				if(debug['c'])
326*e887ea33SDavid du Colombier 					Bprint(&bso, "%s calls %s\n", TNAME, s->name);
327*e887ea33SDavid du Colombier 				switch(s->type) {
328*e887ea33SDavid du Colombier 				default:
329*e887ea33SDavid du Colombier 					diag("undefined: %s in %s", s->name, TNAME);
330*e887ea33SDavid du Colombier 					s->type = STEXT;
331*e887ea33SDavid du Colombier 					s->value = vexit;
332*e887ea33SDavid du Colombier 					break;	/* or fall through to set offset? */
333*e887ea33SDavid du Colombier 				case STEXT:
334*e887ea33SDavid du Colombier 					p->to.offset = s->value;
335*e887ea33SDavid du Colombier 					break;
336*e887ea33SDavid du Colombier 				case SUNDEF:
337*e887ea33SDavid du Colombier 					p->pcond = UP;
338*e887ea33SDavid du Colombier 					p->to.offset = 0;
339*e887ea33SDavid du Colombier 					break;
340*e887ea33SDavid du Colombier 				}
341*e887ea33SDavid du Colombier 				p->to.type = D_BRANCH;
342*e887ea33SDavid du Colombier 			}
343*e887ea33SDavid du Colombier 		}
344*e887ea33SDavid du Colombier 		if(p->to.type != D_BRANCH || p->pcond == UP)
345*e887ea33SDavid du Colombier 			continue;
346*e887ea33SDavid du Colombier 		c = p->to.offset;
347*e887ea33SDavid du Colombier 		for(q = firstp; q != P;) {
348*e887ea33SDavid du Colombier 			if(q->forwd != P)
349*e887ea33SDavid du Colombier 			if(c >= q->forwd->pc) {
350*e887ea33SDavid du Colombier 				q = q->forwd;
351*e887ea33SDavid du Colombier 				continue;
352*e887ea33SDavid du Colombier 			}
353*e887ea33SDavid du Colombier 			if(c == q->pc)
354*e887ea33SDavid du Colombier 				break;
355*e887ea33SDavid du Colombier 			q = q->link;
356*e887ea33SDavid du Colombier 		}
357*e887ea33SDavid du Colombier 		if(q == P) {
358*e887ea33SDavid du Colombier 			diag("branch out of range in %s\n%P", TNAME, p);
359*e887ea33SDavid du Colombier 			p->to.type = D_NONE;
360*e887ea33SDavid du Colombier 		}
361*e887ea33SDavid du Colombier 		p->pcond = q;
362*e887ea33SDavid du Colombier 	}
363*e887ea33SDavid du Colombier 
364*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
365*e887ea33SDavid du Colombier 		if(p->as == ATEXT)
366*e887ea33SDavid du Colombier 			curtext = p;
367*e887ea33SDavid du Colombier 		p->mark = 0;	/* initialization for follow */
368*e887ea33SDavid du Colombier 		if(p->pcond != P && p->pcond != UP) {
369*e887ea33SDavid du Colombier 			p->pcond = brloop(p->pcond);
370*e887ea33SDavid du Colombier 			if(p->pcond != P)
371*e887ea33SDavid du Colombier 			if(p->to.type == D_BRANCH)
372*e887ea33SDavid du Colombier 				p->to.offset = p->pcond->pc;
373*e887ea33SDavid du Colombier 		}
374*e887ea33SDavid du Colombier 	}
375*e887ea33SDavid du Colombier }
376*e887ea33SDavid du Colombier 
377*e887ea33SDavid du Colombier #define	LOG	5
378*e887ea33SDavid du Colombier void
mkfwd(void)379*e887ea33SDavid du Colombier mkfwd(void)
380*e887ea33SDavid du Colombier {
381*e887ea33SDavid du Colombier 	Prog *p;
382*e887ea33SDavid du Colombier 	int i;
383*e887ea33SDavid du Colombier 	long dwn[LOG], cnt[LOG];
384*e887ea33SDavid du Colombier 	Prog *lst[LOG];
385*e887ea33SDavid du Colombier 
386*e887ea33SDavid du Colombier 	for(i=0; i<LOG; i++) {
387*e887ea33SDavid du Colombier 		if(i == 0)
388*e887ea33SDavid du Colombier 			cnt[i] = 1; else
389*e887ea33SDavid du Colombier 			cnt[i] = LOG * cnt[i-1];
390*e887ea33SDavid du Colombier 		dwn[i] = 1;
391*e887ea33SDavid du Colombier 		lst[i] = P;
392*e887ea33SDavid du Colombier 	}
393*e887ea33SDavid du Colombier 	i = 0;
394*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
395*e887ea33SDavid du Colombier 		if(p->as == ATEXT)
396*e887ea33SDavid du Colombier 			curtext = p;
397*e887ea33SDavid du Colombier 		i--;
398*e887ea33SDavid du Colombier 		if(i < 0)
399*e887ea33SDavid du Colombier 			i = LOG-1;
400*e887ea33SDavid du Colombier 		p->forwd = P;
401*e887ea33SDavid du Colombier 		dwn[i]--;
402*e887ea33SDavid du Colombier 		if(dwn[i] <= 0) {
403*e887ea33SDavid du Colombier 			dwn[i] = cnt[i];
404*e887ea33SDavid du Colombier 			if(lst[i] != P)
405*e887ea33SDavid du Colombier 				lst[i]->forwd = p;
406*e887ea33SDavid du Colombier 			lst[i] = p;
407*e887ea33SDavid du Colombier 		}
408*e887ea33SDavid du Colombier 	}
409*e887ea33SDavid du Colombier }
410*e887ea33SDavid du Colombier 
411*e887ea33SDavid du Colombier Prog*
brloop(Prog * p)412*e887ea33SDavid du Colombier brloop(Prog *p)
413*e887ea33SDavid du Colombier {
414*e887ea33SDavid du Colombier 	int c;
415*e887ea33SDavid du Colombier 	Prog *q;
416*e887ea33SDavid du Colombier 
417*e887ea33SDavid du Colombier 	c = 0;
418*e887ea33SDavid du Colombier 	for(q = p; q != P; q = q->pcond) {
419*e887ea33SDavid du Colombier 		if(q->as != AJMP)
420*e887ea33SDavid du Colombier 			break;
421*e887ea33SDavid du Colombier 		c++;
422*e887ea33SDavid du Colombier 		if(c >= 5000)
423*e887ea33SDavid du Colombier 			return P;
424*e887ea33SDavid du Colombier 	}
425*e887ea33SDavid du Colombier 	return q;
426*e887ea33SDavid du Colombier }
427*e887ea33SDavid du Colombier 
428*e887ea33SDavid du Colombier void
dostkoff(void)429*e887ea33SDavid du Colombier dostkoff(void)
430*e887ea33SDavid du Colombier {
431*e887ea33SDavid du Colombier 	Prog *p, *q;
432*e887ea33SDavid du Colombier 	long autoffset, deltasp;
433*e887ea33SDavid du Colombier 	int a, f, curframe, curbecome, maxbecome, pcsize;
434*e887ea33SDavid du Colombier 
435*e887ea33SDavid du Colombier 	curframe = 0;
436*e887ea33SDavid du Colombier 	curbecome = 0;
437*e887ea33SDavid du Colombier 	maxbecome = 0;
438*e887ea33SDavid du Colombier 	curtext = 0;
439*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
440*e887ea33SDavid du Colombier 
441*e887ea33SDavid du Colombier 		/* find out how much arg space is used in this TEXT */
442*e887ea33SDavid du Colombier 		if(p->to.type == (D_INDIR+D_SP))
443*e887ea33SDavid du Colombier 			if(p->to.offset > curframe)
444*e887ea33SDavid du Colombier 				curframe = p->to.offset;
445*e887ea33SDavid du Colombier 
446*e887ea33SDavid du Colombier 		switch(p->as) {
447*e887ea33SDavid du Colombier 		case ATEXT:
448*e887ea33SDavid du Colombier 			if(curtext && curtext->from.sym) {
449*e887ea33SDavid du Colombier 				curtext->from.sym->frame = curframe;
450*e887ea33SDavid du Colombier 				curtext->from.sym->become = curbecome;
451*e887ea33SDavid du Colombier 				if(curbecome > maxbecome)
452*e887ea33SDavid du Colombier 					maxbecome = curbecome;
453*e887ea33SDavid du Colombier 			}
454*e887ea33SDavid du Colombier 			curframe = 0;
455*e887ea33SDavid du Colombier 			curbecome = 0;
456*e887ea33SDavid du Colombier 
457*e887ea33SDavid du Colombier 			curtext = p;
458*e887ea33SDavid du Colombier 			break;
459*e887ea33SDavid du Colombier 
460*e887ea33SDavid du Colombier 		case ARET:
461*e887ea33SDavid du Colombier 			/* special form of RET is BECOME */
462*e887ea33SDavid du Colombier 			if(p->from.type == D_CONST)
463*e887ea33SDavid du Colombier 				if(p->from.offset > curbecome)
464*e887ea33SDavid du Colombier 					curbecome = p->from.offset;
465*e887ea33SDavid du Colombier 			break;
466*e887ea33SDavid du Colombier 		}
467*e887ea33SDavid du Colombier 	}
468*e887ea33SDavid du Colombier 	if(curtext && curtext->from.sym) {
469*e887ea33SDavid du Colombier 		curtext->from.sym->frame = curframe;
470*e887ea33SDavid du Colombier 		curtext->from.sym->become = curbecome;
471*e887ea33SDavid du Colombier 		if(curbecome > maxbecome)
472*e887ea33SDavid du Colombier 			maxbecome = curbecome;
473*e887ea33SDavid du Colombier 	}
474*e887ea33SDavid du Colombier 
475*e887ea33SDavid du Colombier 	if(debug['b'])
476*e887ea33SDavid du Colombier 		print("max become = %d\n", maxbecome);
477*e887ea33SDavid du Colombier 	xdefine("ALEFbecome", STEXT, maxbecome);
478*e887ea33SDavid du Colombier 
479*e887ea33SDavid du Colombier 	curtext = 0;
480*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
481*e887ea33SDavid du Colombier 		switch(p->as) {
482*e887ea33SDavid du Colombier 		case ATEXT:
483*e887ea33SDavid du Colombier 			curtext = p;
484*e887ea33SDavid du Colombier 			break;
485*e887ea33SDavid du Colombier 		case ACALL:
486*e887ea33SDavid du Colombier 			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
487*e887ea33SDavid du Colombier 				f = maxbecome - curtext->from.sym->frame;
488*e887ea33SDavid du Colombier 				if(f <= 0)
489*e887ea33SDavid du Colombier 					break;
490*e887ea33SDavid du Colombier 				/* calling a become or calling a variable */
491*e887ea33SDavid du Colombier 				if(p->to.sym == S || p->to.sym->become) {
492*e887ea33SDavid du Colombier 					curtext->to.offset += f;
493*e887ea33SDavid du Colombier 					if(debug['b']) {
494*e887ea33SDavid du Colombier 						curp = p;
495*e887ea33SDavid du Colombier 						print("%D calling %D increase %d\n",
496*e887ea33SDavid du Colombier 							&curtext->from, &p->to, f);
497*e887ea33SDavid du Colombier 					}
498*e887ea33SDavid du Colombier 				}
499*e887ea33SDavid du Colombier 			}
500*e887ea33SDavid du Colombier 			break;
501*e887ea33SDavid du Colombier 		}
502*e887ea33SDavid du Colombier 	}
503*e887ea33SDavid du Colombier 
504*e887ea33SDavid du Colombier 	autoffset = 0;
505*e887ea33SDavid du Colombier 	deltasp = 0;
506*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
507*e887ea33SDavid du Colombier 		if(p->as == ATEXT) {
508*e887ea33SDavid du Colombier 			curtext = p;
509*e887ea33SDavid du Colombier 			autoffset = p->to.offset;
510*e887ea33SDavid du Colombier 			if(autoffset < 0)
511*e887ea33SDavid du Colombier 				autoffset = 0;
512*e887ea33SDavid du Colombier 			if(autoffset) {
513*e887ea33SDavid du Colombier 				p = appendp(p);
514*e887ea33SDavid du Colombier 				p->as = AADJSP;
515*e887ea33SDavid du Colombier 				p->from.type = D_CONST;
516*e887ea33SDavid du Colombier 				p->from.offset = autoffset;
517*e887ea33SDavid du Colombier 			}
518*e887ea33SDavid du Colombier 			deltasp = autoffset;
519*e887ea33SDavid du Colombier 		}
520*e887ea33SDavid du Colombier 		pcsize = p->mode/8;
521*e887ea33SDavid du Colombier 		a = p->from.type;
522*e887ea33SDavid du Colombier 		if(a == D_AUTO)
523*e887ea33SDavid du Colombier 			p->from.offset += deltasp;
524*e887ea33SDavid du Colombier 		if(a == D_PARAM)
525*e887ea33SDavid du Colombier 			p->from.offset += deltasp + pcsize;
526*e887ea33SDavid du Colombier 		a = p->to.type;
527*e887ea33SDavid du Colombier 		if(a == D_AUTO)
528*e887ea33SDavid du Colombier 			p->to.offset += deltasp;
529*e887ea33SDavid du Colombier 		if(a == D_PARAM)
530*e887ea33SDavid du Colombier 			p->to.offset += deltasp + pcsize;
531*e887ea33SDavid du Colombier 
532*e887ea33SDavid du Colombier 		switch(p->as) {
533*e887ea33SDavid du Colombier 		default:
534*e887ea33SDavid du Colombier 			continue;
535*e887ea33SDavid du Colombier 		case APUSHL:
536*e887ea33SDavid du Colombier 		case APUSHFL:
537*e887ea33SDavid du Colombier 			deltasp += 4;
538*e887ea33SDavid du Colombier 			continue;
539*e887ea33SDavid du Colombier 		case APUSHQ:
540*e887ea33SDavid du Colombier 		case APUSHFQ:
541*e887ea33SDavid du Colombier 			deltasp += 8;
542*e887ea33SDavid du Colombier 			continue;
543*e887ea33SDavid du Colombier 		case APUSHW:
544*e887ea33SDavid du Colombier 		case APUSHFW:
545*e887ea33SDavid du Colombier 			deltasp += 2;
546*e887ea33SDavid du Colombier 			continue;
547*e887ea33SDavid du Colombier 		case APOPL:
548*e887ea33SDavid du Colombier 		case APOPFL:
549*e887ea33SDavid du Colombier 			deltasp -= 4;
550*e887ea33SDavid du Colombier 			continue;
551*e887ea33SDavid du Colombier 		case APOPQ:
552*e887ea33SDavid du Colombier 		case APOPFQ:
553*e887ea33SDavid du Colombier 			deltasp -= 8;
554*e887ea33SDavid du Colombier 			continue;
555*e887ea33SDavid du Colombier 		case APOPW:
556*e887ea33SDavid du Colombier 		case APOPFW:
557*e887ea33SDavid du Colombier 			deltasp -= 2;
558*e887ea33SDavid du Colombier 			continue;
559*e887ea33SDavid du Colombier 		case ARET:
560*e887ea33SDavid du Colombier 			break;
561*e887ea33SDavid du Colombier 		}
562*e887ea33SDavid du Colombier 
563*e887ea33SDavid du Colombier 		if(autoffset != deltasp)
564*e887ea33SDavid du Colombier 			diag("unbalanced PUSH/POP");
565*e887ea33SDavid du Colombier 		if(p->from.type == D_CONST)
566*e887ea33SDavid du Colombier 			goto become;
567*e887ea33SDavid du Colombier 
568*e887ea33SDavid du Colombier 		if(autoffset) {
569*e887ea33SDavid du Colombier 			q = p;
570*e887ea33SDavid du Colombier 			p = appendp(p);
571*e887ea33SDavid du Colombier 			p->as = ARET;
572*e887ea33SDavid du Colombier 
573*e887ea33SDavid du Colombier 			q->as = AADJSP;
574*e887ea33SDavid du Colombier 			q->from.type = D_CONST;
575*e887ea33SDavid du Colombier 			q->from.offset = -autoffset;
576*e887ea33SDavid du Colombier 		}
577*e887ea33SDavid du Colombier 		continue;
578*e887ea33SDavid du Colombier 
579*e887ea33SDavid du Colombier 	become:
580*e887ea33SDavid du Colombier 		q = p;
581*e887ea33SDavid du Colombier 		p = appendp(p);
582*e887ea33SDavid du Colombier 		p->as = AJMP;
583*e887ea33SDavid du Colombier 		p->to = q->to;
584*e887ea33SDavid du Colombier 		p->pcond = q->pcond;
585*e887ea33SDavid du Colombier 
586*e887ea33SDavid du Colombier 		q->as = AADJSP;
587*e887ea33SDavid du Colombier 		q->from = zprg.from;
588*e887ea33SDavid du Colombier 		q->from.type = D_CONST;
589*e887ea33SDavid du Colombier 		q->from.offset = -autoffset;
590*e887ea33SDavid du Colombier 		q->to = zprg.to;
591*e887ea33SDavid du Colombier 		continue;
592*e887ea33SDavid du Colombier 	}
593*e887ea33SDavid du Colombier }
594*e887ea33SDavid du Colombier 
595*e887ea33SDavid du Colombier vlong
atolwhex(char * s)596*e887ea33SDavid du Colombier atolwhex(char *s)
597*e887ea33SDavid du Colombier {
598*e887ea33SDavid du Colombier 	vlong n;
599*e887ea33SDavid du Colombier 	int f;
600*e887ea33SDavid du Colombier 
601*e887ea33SDavid du Colombier 	n = 0;
602*e887ea33SDavid du Colombier 	f = 0;
603*e887ea33SDavid du Colombier 	while(*s == ' ' || *s == '\t')
604*e887ea33SDavid du Colombier 		s++;
605*e887ea33SDavid du Colombier 	if(*s == '-' || *s == '+') {
606*e887ea33SDavid du Colombier 		if(*s++ == '-')
607*e887ea33SDavid du Colombier 			f = 1;
608*e887ea33SDavid du Colombier 		while(*s == ' ' || *s == '\t')
609*e887ea33SDavid du Colombier 			s++;
610*e887ea33SDavid du Colombier 	}
611*e887ea33SDavid du Colombier 	if(s[0]=='0' && s[1]){
612*e887ea33SDavid du Colombier 		if(s[1]=='x' || s[1]=='X'){
613*e887ea33SDavid du Colombier 			s += 2;
614*e887ea33SDavid du Colombier 			for(;;){
615*e887ea33SDavid du Colombier 				if(*s >= '0' && *s <= '9')
616*e887ea33SDavid du Colombier 					n = n*16 + *s++ - '0';
617*e887ea33SDavid du Colombier 				else if(*s >= 'a' && *s <= 'f')
618*e887ea33SDavid du Colombier 					n = n*16 + *s++ - 'a' + 10;
619*e887ea33SDavid du Colombier 				else if(*s >= 'A' && *s <= 'F')
620*e887ea33SDavid du Colombier 					n = n*16 + *s++ - 'A' + 10;
621*e887ea33SDavid du Colombier 				else
622*e887ea33SDavid du Colombier 					break;
623*e887ea33SDavid du Colombier 			}
624*e887ea33SDavid du Colombier 		} else
625*e887ea33SDavid du Colombier 			while(*s >= '0' && *s <= '7')
626*e887ea33SDavid du Colombier 				n = n*8 + *s++ - '0';
627*e887ea33SDavid du Colombier 	} else
628*e887ea33SDavid du Colombier 		while(*s >= '0' && *s <= '9')
629*e887ea33SDavid du Colombier 			n = n*10 + *s++ - '0';
630*e887ea33SDavid du Colombier 	if(f)
631*e887ea33SDavid du Colombier 		n = -n;
632*e887ea33SDavid du Colombier 	return n;
633*e887ea33SDavid du Colombier }
634*e887ea33SDavid du Colombier 
635*e887ea33SDavid du Colombier void
undef(void)636*e887ea33SDavid du Colombier undef(void)
637*e887ea33SDavid du Colombier {
638*e887ea33SDavid du Colombier 	int i;
639*e887ea33SDavid du Colombier 	Sym *s;
640*e887ea33SDavid du Colombier 
641*e887ea33SDavid du Colombier 	for(i=0; i<NHASH; i++)
642*e887ea33SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link)
643*e887ea33SDavid du Colombier 		if(s->type == SXREF)
644*e887ea33SDavid du Colombier 			diag("%s: not defined", s->name);
645*e887ea33SDavid du Colombier }
646*e887ea33SDavid du Colombier 
647*e887ea33SDavid du Colombier void
import(void)648*e887ea33SDavid du Colombier import(void)
649*e887ea33SDavid du Colombier {
650*e887ea33SDavid du Colombier 	int i;
651*e887ea33SDavid du Colombier 	Sym *s;
652*e887ea33SDavid du Colombier 
653*e887ea33SDavid du Colombier 	for(i = 0; i < NHASH; i++)
654*e887ea33SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
655*e887ea33SDavid du Colombier 			if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
656*e887ea33SDavid du Colombier 				if(s->value != 0)
657*e887ea33SDavid du Colombier 					diag("value != 0 on SXREF");
658*e887ea33SDavid du Colombier 				undefsym(s);
659*e887ea33SDavid du Colombier 				Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value);
660*e887ea33SDavid du Colombier 				if(debug['S'])
661*e887ea33SDavid du Colombier 					s->sig = 0;
662*e887ea33SDavid du Colombier 			}
663*e887ea33SDavid du Colombier }
664*e887ea33SDavid du Colombier 
665*e887ea33SDavid du Colombier void
ckoff(Sym * s,long v)666*e887ea33SDavid du Colombier ckoff(Sym *s, long v)
667*e887ea33SDavid du Colombier {
668*e887ea33SDavid du Colombier 	if(v < 0 || v >= 1<<Roffset)
669*e887ea33SDavid du Colombier 		diag("relocation offset %ld for %s out of range", v, s->name);
670*e887ea33SDavid du Colombier }
671*e887ea33SDavid du Colombier 
672*e887ea33SDavid du Colombier static Prog*
newdata(Sym * s,int o,int w,int t)673*e887ea33SDavid du Colombier newdata(Sym *s, int o, int w, int t)
674*e887ea33SDavid du Colombier {
675*e887ea33SDavid du Colombier 	Prog *p;
676*e887ea33SDavid du Colombier 
677*e887ea33SDavid du Colombier 	p = prg();
678*e887ea33SDavid du Colombier 	if(edatap == P)
679*e887ea33SDavid du Colombier 		datap = p;
680*e887ea33SDavid du Colombier 	else
681*e887ea33SDavid du Colombier 		edatap->link = p;
682*e887ea33SDavid du Colombier 	edatap = p;
683*e887ea33SDavid du Colombier 	p->as = ADATA;
684*e887ea33SDavid du Colombier 	p->width = w;
685*e887ea33SDavid du Colombier 	p->from.scale = w;
686*e887ea33SDavid du Colombier 	p->from.type = t;
687*e887ea33SDavid du Colombier 	p->from.sym = s;
688*e887ea33SDavid du Colombier 	p->from.offset = o;
689*e887ea33SDavid du Colombier 	p->to.type = D_CONST;
690*e887ea33SDavid du Colombier 	return p;
691*e887ea33SDavid du Colombier }
692*e887ea33SDavid du Colombier 
693*e887ea33SDavid du Colombier void
export(void)694*e887ea33SDavid du Colombier export(void)
695*e887ea33SDavid du Colombier {
696*e887ea33SDavid du Colombier 	int i, j, n, off, nb, sv, ne;
697*e887ea33SDavid du Colombier 	Sym *s, *et, *str, **esyms;
698*e887ea33SDavid du Colombier 	Prog *p;
699*e887ea33SDavid du Colombier 	char buf[NSNAME], *t;
700*e887ea33SDavid du Colombier 
701*e887ea33SDavid du Colombier 	n = 0;
702*e887ea33SDavid du Colombier 	for(i = 0; i < NHASH; i++)
703*e887ea33SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
704*e887ea33SDavid du Colombier 			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
705*e887ea33SDavid du Colombier 				n++;
706*e887ea33SDavid du Colombier 	esyms = malloc(n*sizeof(Sym*));
707*e887ea33SDavid du Colombier 	ne = n;
708*e887ea33SDavid du Colombier 	n = 0;
709*e887ea33SDavid du Colombier 	for(i = 0; i < NHASH; i++)
710*e887ea33SDavid du Colombier 		for(s = hash[i]; s != S; s = s->link)
711*e887ea33SDavid du Colombier 			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
712*e887ea33SDavid du Colombier 				esyms[n++] = s;
713*e887ea33SDavid du Colombier 	for(i = 0; i < ne-1; i++)
714*e887ea33SDavid du Colombier 		for(j = i+1; j < ne; j++)
715*e887ea33SDavid du Colombier 			if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
716*e887ea33SDavid du Colombier 				s = esyms[i];
717*e887ea33SDavid du Colombier 				esyms[i] = esyms[j];
718*e887ea33SDavid du Colombier 				esyms[j] = s;
719*e887ea33SDavid du Colombier 			}
720*e887ea33SDavid du Colombier 
721*e887ea33SDavid du Colombier 	nb = 0;
722*e887ea33SDavid du Colombier 	off = 0;
723*e887ea33SDavid du Colombier 	et = lookup(EXPTAB, 0);
724*e887ea33SDavid du Colombier 	if(et->type != 0 && et->type != SXREF)
725*e887ea33SDavid du Colombier 		diag("%s already defined", EXPTAB);
726*e887ea33SDavid du Colombier 	et->type = SDATA;
727*e887ea33SDavid du Colombier 	str = lookup(".string", 0);
728*e887ea33SDavid du Colombier 	if(str->type == 0)
729*e887ea33SDavid du Colombier 		str->type = SDATA;
730*e887ea33SDavid du Colombier 	sv = str->value;
731*e887ea33SDavid du Colombier 	for(i = 0; i < ne; i++){
732*e887ea33SDavid du Colombier 		s = esyms[i];
733*e887ea33SDavid du Colombier 		if(debug['S'])
734*e887ea33SDavid du Colombier 			s->sig = 0;
735*e887ea33SDavid du Colombier 		/* Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type); */
736*e887ea33SDavid du Colombier 
737*e887ea33SDavid du Colombier 		/* signature */
738*e887ea33SDavid du Colombier 		p = newdata(et, off, sizeof(long), D_EXTERN);
739*e887ea33SDavid du Colombier 		off += sizeof(long);
740*e887ea33SDavid du Colombier 		p->to.offset = s->sig;
741*e887ea33SDavid du Colombier 
742*e887ea33SDavid du Colombier 		/* address */
743*e887ea33SDavid du Colombier 		p = newdata(et, off, sizeof(long), D_EXTERN);
744*e887ea33SDavid du Colombier 		off += sizeof(long);
745*e887ea33SDavid du Colombier 		p->to.type = D_ADDR;
746*e887ea33SDavid du Colombier 		p->to.index = D_EXTERN;
747*e887ea33SDavid du Colombier 		p->to.sym = s;
748*e887ea33SDavid du Colombier 
749*e887ea33SDavid du Colombier 		/* string */
750*e887ea33SDavid du Colombier 		t = s->name;
751*e887ea33SDavid du Colombier 		n = strlen(t)+1;
752*e887ea33SDavid du Colombier 		for(;;){
753*e887ea33SDavid du Colombier 			buf[nb++] = *t;
754*e887ea33SDavid du Colombier 			sv++;
755*e887ea33SDavid du Colombier 			if(nb >= NSNAME){
756*e887ea33SDavid du Colombier 				p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
757*e887ea33SDavid du Colombier 				p->to.type = D_SCONST;
758*e887ea33SDavid du Colombier 				memmove(p->to.scon, buf, NSNAME);
759*e887ea33SDavid du Colombier 				nb = 0;
760*e887ea33SDavid du Colombier 			}
761*e887ea33SDavid du Colombier 			if(*t++ == 0)
762*e887ea33SDavid du Colombier 				break;
763*e887ea33SDavid du Colombier 		}
764*e887ea33SDavid du Colombier 
765*e887ea33SDavid du Colombier 		/* name */
766*e887ea33SDavid du Colombier 		p = newdata(et, off, sizeof(long), D_EXTERN);
767*e887ea33SDavid du Colombier 		off += sizeof(long);
768*e887ea33SDavid du Colombier 		p->to.type = D_ADDR;
769*e887ea33SDavid du Colombier 		p->to.index = D_STATIC;
770*e887ea33SDavid du Colombier 		p->to.sym = str;
771*e887ea33SDavid du Colombier 		p->to.offset = sv-n;
772*e887ea33SDavid du Colombier 	}
773*e887ea33SDavid du Colombier 
774*e887ea33SDavid du Colombier 	if(nb > 0){
775*e887ea33SDavid du Colombier 		p = newdata(str, sv-nb, nb, D_STATIC);
776*e887ea33SDavid du Colombier 		p->to.type = D_SCONST;
777*e887ea33SDavid du Colombier 		memmove(p->to.scon, buf, nb);
778*e887ea33SDavid du Colombier 	}
779*e887ea33SDavid du Colombier 
780*e887ea33SDavid du Colombier 	for(i = 0; i < 3; i++){
781*e887ea33SDavid du Colombier 		newdata(et, off, sizeof(long), D_EXTERN);
782*e887ea33SDavid du Colombier 		off += sizeof(long);
783*e887ea33SDavid du Colombier 	}
784*e887ea33SDavid du Colombier 	et->value = off;
785*e887ea33SDavid du Colombier 	if(sv == 0)
786*e887ea33SDavid du Colombier 		sv = 1;
787*e887ea33SDavid du Colombier 	str->value = sv;
788*e887ea33SDavid du Colombier 	exports = ne;
789*e887ea33SDavid du Colombier 	free(esyms);
790*e887ea33SDavid du Colombier }
791