xref: /plan9/sys/src/cmd/6l/asm.c (revision e887ea33cf0b0f75911958e2324340660b13e9eb)
1*e887ea33SDavid du Colombier #include	"l.h"
2*e887ea33SDavid du Colombier 
3*e887ea33SDavid du Colombier #define	Dbufslop	100
4*e887ea33SDavid du Colombier 
5*e887ea33SDavid du Colombier #define PADDR(a)	((a) & ~0xfffffffff0000000ull)
6*e887ea33SDavid du Colombier 
7*e887ea33SDavid du Colombier vlong
8*e887ea33SDavid du Colombier entryvalue(void)
9*e887ea33SDavid du Colombier {
10*e887ea33SDavid du Colombier 	char *a;
11*e887ea33SDavid du Colombier 	Sym *s;
12*e887ea33SDavid du Colombier 
13*e887ea33SDavid du Colombier 	a = INITENTRY;
14*e887ea33SDavid du Colombier 	if(*a >= '0' && *a <= '9')
15*e887ea33SDavid du Colombier 		return atolwhex(a);
16*e887ea33SDavid du Colombier 	s = lookup(a, 0);
17*e887ea33SDavid du Colombier 	if(s->type == 0)
18*e887ea33SDavid du Colombier 		return INITTEXT;
19*e887ea33SDavid du Colombier 	switch(s->type) {
20*e887ea33SDavid du Colombier 	case STEXT:
21*e887ea33SDavid du Colombier 		break;
22*e887ea33SDavid du Colombier 	case SDATA:
23*e887ea33SDavid du Colombier 		if(dlm)
24*e887ea33SDavid du Colombier 			return s->value+INITDAT;
25*e887ea33SDavid du Colombier 	default:
26*e887ea33SDavid du Colombier 		diag("entry not text: %s", s->name);
27*e887ea33SDavid du Colombier 	}
28*e887ea33SDavid du Colombier 	return s->value;
29*e887ea33SDavid du Colombier }
30*e887ea33SDavid du Colombier 
31*e887ea33SDavid du Colombier void
32*e887ea33SDavid du Colombier wputl(ushort w)
33*e887ea33SDavid du Colombier {
34*e887ea33SDavid du Colombier 	cput(w);
35*e887ea33SDavid du Colombier 	cput(w>>8);
36*e887ea33SDavid du Colombier }
37*e887ea33SDavid du Colombier 
38*e887ea33SDavid du Colombier void
39*e887ea33SDavid du Colombier wput(ushort w)
40*e887ea33SDavid du Colombier {
41*e887ea33SDavid du Colombier 	cput(w>>8);
42*e887ea33SDavid du Colombier 	cput(w);
43*e887ea33SDavid du Colombier }
44*e887ea33SDavid du Colombier 
45*e887ea33SDavid du Colombier void
46*e887ea33SDavid du Colombier lput(long l)
47*e887ea33SDavid du Colombier {
48*e887ea33SDavid du Colombier 	cput(l>>24);
49*e887ea33SDavid du Colombier 	cput(l>>16);
50*e887ea33SDavid du Colombier 	cput(l>>8);
51*e887ea33SDavid du Colombier 	cput(l);
52*e887ea33SDavid du Colombier }
53*e887ea33SDavid du Colombier 
54*e887ea33SDavid du Colombier void
55*e887ea33SDavid du Colombier llput(vlong v)
56*e887ea33SDavid du Colombier {
57*e887ea33SDavid du Colombier 	lput(v>>32);
58*e887ea33SDavid du Colombier 	lput(v);
59*e887ea33SDavid du Colombier }
60*e887ea33SDavid du Colombier 
61*e887ea33SDavid du Colombier void
62*e887ea33SDavid du Colombier lputl(long l)
63*e887ea33SDavid du Colombier {
64*e887ea33SDavid du Colombier 	cput(l);
65*e887ea33SDavid du Colombier 	cput(l>>8);
66*e887ea33SDavid du Colombier 	cput(l>>16);
67*e887ea33SDavid du Colombier 	cput(l>>24);
68*e887ea33SDavid du Colombier }
69*e887ea33SDavid du Colombier 
70*e887ea33SDavid du Colombier void
71*e887ea33SDavid du Colombier strnput(char *s, int n)
72*e887ea33SDavid du Colombier {
73*e887ea33SDavid du Colombier 	for(; *s && n > 0; s++){
74*e887ea33SDavid du Colombier 		cput(*s);
75*e887ea33SDavid du Colombier 		n--;
76*e887ea33SDavid du Colombier 	}
77*e887ea33SDavid du Colombier 	while(n > 0){
78*e887ea33SDavid du Colombier 		cput(0);
79*e887ea33SDavid du Colombier 		n--;
80*e887ea33SDavid du Colombier 	}
81*e887ea33SDavid du Colombier }
82*e887ea33SDavid du Colombier 
83*e887ea33SDavid du Colombier void
84*e887ea33SDavid du Colombier asmb(void)
85*e887ea33SDavid du Colombier {
86*e887ea33SDavid du Colombier 	Prog *p;
87*e887ea33SDavid du Colombier 	long v, magic;
88*e887ea33SDavid du Colombier 	int a;
89*e887ea33SDavid du Colombier 	uchar *op1;
90*e887ea33SDavid du Colombier 	vlong vl;
91*e887ea33SDavid du Colombier 
92*e887ea33SDavid du Colombier 	if(debug['v'])
93*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f asmb\n", cputime());
94*e887ea33SDavid du Colombier 	Bflush(&bso);
95*e887ea33SDavid du Colombier 
96*e887ea33SDavid du Colombier 	seek(cout, HEADR, 0);
97*e887ea33SDavid du Colombier 	pc = INITTEXT;
98*e887ea33SDavid du Colombier 	curp = firstp;
99*e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
100*e887ea33SDavid du Colombier 		if(p->as == ATEXT)
101*e887ea33SDavid du Colombier 			curtext = p;
102*e887ea33SDavid du Colombier 		if(p->pc != pc) {
103*e887ea33SDavid du Colombier 			if(!debug['a'])
104*e887ea33SDavid du Colombier 				print("%P\n", curp);
105*e887ea33SDavid du Colombier 			diag("phase error %llux sb %llux in %s", p->pc, pc, TNAME);
106*e887ea33SDavid du Colombier 			pc = p->pc;
107*e887ea33SDavid du Colombier 		}
108*e887ea33SDavid du Colombier 		curp = p;
109*e887ea33SDavid du Colombier 		asmins(p);
110*e887ea33SDavid du Colombier 		a = (andptr - and);
111*e887ea33SDavid du Colombier 		if(cbc < a)
112*e887ea33SDavid du Colombier 			cflush();
113*e887ea33SDavid du Colombier 		if(debug['a']) {
114*e887ea33SDavid du Colombier 			Bprint(&bso, pcstr, pc);
115*e887ea33SDavid du Colombier 			for(op1 = and; op1 < andptr; op1++)
116*e887ea33SDavid du Colombier 				Bprint(&bso, "%.2ux", *op1 & 0xff);
117*e887ea33SDavid du Colombier 			Bprint(&bso, "\t%P\n", curp);
118*e887ea33SDavid du Colombier 		}
119*e887ea33SDavid du Colombier 		if(dlm) {
120*e887ea33SDavid du Colombier 			if(p->as == ATEXT)
121*e887ea33SDavid du Colombier 				reloca = nil;
122*e887ea33SDavid du Colombier 			else if(reloca != nil)
123*e887ea33SDavid du Colombier 				diag("reloc failure: %P", curp);
124*e887ea33SDavid du Colombier 		}
125*e887ea33SDavid du Colombier 		memmove(cbp, and, a);
126*e887ea33SDavid du Colombier 		cbp += a;
127*e887ea33SDavid du Colombier 		pc += a;
128*e887ea33SDavid du Colombier 		cbc -= a;
129*e887ea33SDavid du Colombier 	}
130*e887ea33SDavid du Colombier 	cflush();
131*e887ea33SDavid du Colombier 	switch(HEADTYPE) {
132*e887ea33SDavid du Colombier 	default:
133*e887ea33SDavid du Colombier 		diag("unknown header type %ld", HEADTYPE);
134*e887ea33SDavid du Colombier 	case 2:
135*e887ea33SDavid du Colombier 	case 5:
136*e887ea33SDavid du Colombier 		seek(cout, HEADR+textsize, 0);
137*e887ea33SDavid du Colombier 		break;
138*e887ea33SDavid du Colombier 	}
139*e887ea33SDavid du Colombier 
140*e887ea33SDavid du Colombier 	if(debug['v'])
141*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f datblk\n", cputime());
142*e887ea33SDavid du Colombier 	Bflush(&bso);
143*e887ea33SDavid du Colombier 
144*e887ea33SDavid du Colombier 	if(dlm){
145*e887ea33SDavid du Colombier 		char buf[8];
146*e887ea33SDavid du Colombier 
147*e887ea33SDavid du Colombier 		write(cout, buf, INITDAT-textsize);
148*e887ea33SDavid du Colombier 		textsize = INITDAT;
149*e887ea33SDavid du Colombier 	}
150*e887ea33SDavid du Colombier 
151*e887ea33SDavid du Colombier 	for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
152*e887ea33SDavid du Colombier 		if(datsize-v > sizeof(buf)-Dbufslop)
153*e887ea33SDavid du Colombier 			datblk(v, sizeof(buf)-Dbufslop);
154*e887ea33SDavid du Colombier 		else
155*e887ea33SDavid du Colombier 			datblk(v, datsize-v);
156*e887ea33SDavid du Colombier 	}
157*e887ea33SDavid du Colombier 
158*e887ea33SDavid du Colombier 	symsize = 0;
159*e887ea33SDavid du Colombier 	spsize = 0;
160*e887ea33SDavid du Colombier 	lcsize = 0;
161*e887ea33SDavid du Colombier 	if(!debug['s']) {
162*e887ea33SDavid du Colombier 		if(debug['v'])
163*e887ea33SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
164*e887ea33SDavid du Colombier 		Bflush(&bso);
165*e887ea33SDavid du Colombier 		switch(HEADTYPE) {
166*e887ea33SDavid du Colombier 		default:
167*e887ea33SDavid du Colombier 		case 2:
168*e887ea33SDavid du Colombier 		case 5:
169*e887ea33SDavid du Colombier 			seek(cout, HEADR+textsize+datsize, 0);
170*e887ea33SDavid du Colombier 			break;
171*e887ea33SDavid du Colombier 		}
172*e887ea33SDavid du Colombier 		if(!debug['s'])
173*e887ea33SDavid du Colombier 			asmsym();
174*e887ea33SDavid du Colombier 		if(debug['v'])
175*e887ea33SDavid du Colombier 			Bprint(&bso, "%5.2f sp\n", cputime());
176*e887ea33SDavid du Colombier 		Bflush(&bso);
177*e887ea33SDavid du Colombier 		if(debug['v'])
178*e887ea33SDavid du Colombier 			Bprint(&bso, "%5.2f pc\n", cputime());
179*e887ea33SDavid du Colombier 		Bflush(&bso);
180*e887ea33SDavid du Colombier 		if(!debug['s'])
181*e887ea33SDavid du Colombier 			asmlc();
182*e887ea33SDavid du Colombier 		if(dlm)
183*e887ea33SDavid du Colombier 			asmdyn();
184*e887ea33SDavid du Colombier 		cflush();
185*e887ea33SDavid du Colombier 	}
186*e887ea33SDavid du Colombier 	else if(dlm){
187*e887ea33SDavid du Colombier 		seek(cout, HEADR+textsize+datsize, 0);
188*e887ea33SDavid du Colombier 		asmdyn();
189*e887ea33SDavid du Colombier 		cflush();
190*e887ea33SDavid du Colombier 	}
191*e887ea33SDavid du Colombier 	if(debug['v'])
192*e887ea33SDavid du Colombier 		Bprint(&bso, "%5.2f headr\n", cputime());
193*e887ea33SDavid du Colombier 	Bflush(&bso);
194*e887ea33SDavid du Colombier 	seek(cout, 0L, 0);
195*e887ea33SDavid du Colombier 	switch(HEADTYPE) {
196*e887ea33SDavid du Colombier 	default:
197*e887ea33SDavid du Colombier 	case 2:	/* plan9 */
198*e887ea33SDavid du Colombier 		magic = 4*26*26+7;
199*e887ea33SDavid du Colombier 		magic |= 0x00008000;		/* fat header */
200*e887ea33SDavid du Colombier 		if(dlm)
201*e887ea33SDavid du Colombier 			magic |= 0x80000000;	/* dlm */
202*e887ea33SDavid du Colombier 		lput(magic);			/* magic */
203*e887ea33SDavid du Colombier 		lput(textsize);			/* sizes */
204*e887ea33SDavid du Colombier 		lput(datsize);
205*e887ea33SDavid du Colombier 		lput(bsssize);
206*e887ea33SDavid du Colombier 		lput(symsize);			/* nsyms */
207*e887ea33SDavid du Colombier 		vl = entryvalue();
208*e887ea33SDavid du Colombier 		lput(PADDR(vl));		/* va of entry */
209*e887ea33SDavid du Colombier 		lput(spsize);			/* sp offsets */
210*e887ea33SDavid du Colombier 		lput(lcsize);			/* line offsets */
211*e887ea33SDavid du Colombier 		llput(vl);			/* va of entry */
212*e887ea33SDavid du Colombier 		break;
213*e887ea33SDavid du Colombier 	case 3:	/* plan9 */
214*e887ea33SDavid du Colombier 		magic = 4*26*26+7;
215*e887ea33SDavid du Colombier 		if(dlm)
216*e887ea33SDavid du Colombier 			magic |= 0x80000000;
217*e887ea33SDavid du Colombier 		lput(magic);			/* magic */
218*e887ea33SDavid du Colombier 		lput(textsize);			/* sizes */
219*e887ea33SDavid du Colombier 		lput(datsize);
220*e887ea33SDavid du Colombier 		lput(bsssize);
221*e887ea33SDavid du Colombier 		lput(symsize);			/* nsyms */
222*e887ea33SDavid du Colombier 		lput(entryvalue());		/* va of entry */
223*e887ea33SDavid du Colombier 		lput(spsize);			/* sp offsets */
224*e887ea33SDavid du Colombier 		lput(lcsize);			/* line offsets */
225*e887ea33SDavid du Colombier 		break;
226*e887ea33SDavid du Colombier 	case 5:
227*e887ea33SDavid du Colombier 		strnput("\177ELF", 4);		/* e_ident */
228*e887ea33SDavid du Colombier 		cput(1);			/* class = 32 bit */
229*e887ea33SDavid du Colombier 		cput(1);			/* data = LSB */
230*e887ea33SDavid du Colombier 		cput(1);			/* version = CURRENT */
231*e887ea33SDavid du Colombier 		strnput("", 9);
232*e887ea33SDavid du Colombier 		wputl(2);			/* type = EXEC */
233*e887ea33SDavid du Colombier 		if(debug['8'])
234*e887ea33SDavid du Colombier 			wputl(3);		/* machine = 386 */
235*e887ea33SDavid du Colombier 		else
236*e887ea33SDavid du Colombier 			wputl(62);		/* machine = AMD64 */
237*e887ea33SDavid du Colombier 		lputl(1L);			/* version = CURRENT */
238*e887ea33SDavid du Colombier 		lputl(PADDR(entryvalue()));	/* entry vaddr */
239*e887ea33SDavid du Colombier 		lputl(52L);			/* offset to first phdr */
240*e887ea33SDavid du Colombier 		lputl(0L);			/* offset to first shdr */
241*e887ea33SDavid du Colombier 		lputl(0L);			/* processor specific flags */
242*e887ea33SDavid du Colombier 		wputl(52);			/* Ehdr size */
243*e887ea33SDavid du Colombier 		wputl(32);			/* Phdr size */
244*e887ea33SDavid du Colombier 		wputl(3);			/* # of Phdrs */
245*e887ea33SDavid du Colombier 		wputl(0);			/* Shdr size */
246*e887ea33SDavid du Colombier 		wputl(0);			/* # of Shdrs */
247*e887ea33SDavid du Colombier 		wputl(0);			/* Shdr string size */
248*e887ea33SDavid du Colombier 
249*e887ea33SDavid du Colombier 		lputl(1L);			/* text - type = PT_LOAD */
250*e887ea33SDavid du Colombier 		lputl(HEADR);			/* file offset */
251*e887ea33SDavid du Colombier 		lputl(INITTEXT);		/* vaddr */
252*e887ea33SDavid du Colombier 		lputl(PADDR(INITTEXT));		/* paddr */
253*e887ea33SDavid du Colombier 		lputl(textsize);		/* file size */
254*e887ea33SDavid du Colombier 		lputl(textsize);		/* memory size */
255*e887ea33SDavid du Colombier 		lputl(0x05L);			/* protections = RX */
256*e887ea33SDavid du Colombier 		lputl(INITRND);			/* alignment */
257*e887ea33SDavid du Colombier 
258*e887ea33SDavid du Colombier 		lputl(1L);			/* data - type = PT_LOAD */
259*e887ea33SDavid du Colombier 		lputl(HEADR+textsize);		/* file offset */
260*e887ea33SDavid du Colombier 		lputl(INITDAT);			/* vaddr */
261*e887ea33SDavid du Colombier 		lputl(PADDR(INITDAT));		/* paddr */
262*e887ea33SDavid du Colombier 		lputl(datsize);			/* file size */
263*e887ea33SDavid du Colombier 		lputl(datsize+bsssize);		/* memory size */
264*e887ea33SDavid du Colombier 		lputl(0x06L);			/* protections = RW */
265*e887ea33SDavid du Colombier 		lputl(INITRND);			/* alignment */
266*e887ea33SDavid du Colombier 
267*e887ea33SDavid du Colombier 		lputl(0L);			/* data - type = PT_NULL */
268*e887ea33SDavid du Colombier 		lputl(HEADR+textsize+datsize);	/* file offset */
269*e887ea33SDavid du Colombier 		lputl(0L);
270*e887ea33SDavid du Colombier 		lputl(0L);
271*e887ea33SDavid du Colombier 		lputl(symsize);			/* symbol table size */
272*e887ea33SDavid du Colombier 		lputl(lcsize);			/* line number size */
273*e887ea33SDavid du Colombier 		lputl(0x04L);			/* protections = R */
274*e887ea33SDavid du Colombier 		lputl(0x04L);			/* alignment */
275*e887ea33SDavid du Colombier 		break;
276*e887ea33SDavid du Colombier 	}
277*e887ea33SDavid du Colombier 	cflush();
278*e887ea33SDavid du Colombier }
279*e887ea33SDavid du Colombier 
280*e887ea33SDavid du Colombier void
281*e887ea33SDavid du Colombier cflush(void)
282*e887ea33SDavid du Colombier {
283*e887ea33SDavid du Colombier 	int n;
284*e887ea33SDavid du Colombier 
285*e887ea33SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
286*e887ea33SDavid du Colombier 	if(n)
287*e887ea33SDavid du Colombier 		write(cout, buf.cbuf, n);
288*e887ea33SDavid du Colombier 	cbp = buf.cbuf;
289*e887ea33SDavid du Colombier 	cbc = sizeof(buf.cbuf);
290*e887ea33SDavid du Colombier }
291*e887ea33SDavid du Colombier 
292*e887ea33SDavid du Colombier void
293*e887ea33SDavid du Colombier datblk(long s, long n)
294*e887ea33SDavid du Colombier {
295*e887ea33SDavid du Colombier 	Prog *p;
296*e887ea33SDavid du Colombier 	uchar *cast;
297*e887ea33SDavid du Colombier 	long l, fl, j;
298*e887ea33SDavid du Colombier 	vlong o;
299*e887ea33SDavid du Colombier 	int i, c;
300*e887ea33SDavid du Colombier 
301*e887ea33SDavid du Colombier 	memset(buf.dbuf, 0, n+Dbufslop);
302*e887ea33SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
303*e887ea33SDavid du Colombier 		curp = p;
304*e887ea33SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
305*e887ea33SDavid du Colombier 		c = p->from.scale;
306*e887ea33SDavid du Colombier 		i = 0;
307*e887ea33SDavid du Colombier 		if(l < 0) {
308*e887ea33SDavid du Colombier 			if(l+c <= 0)
309*e887ea33SDavid du Colombier 				continue;
310*e887ea33SDavid du Colombier 			while(l < 0) {
311*e887ea33SDavid du Colombier 				l++;
312*e887ea33SDavid du Colombier 				i++;
313*e887ea33SDavid du Colombier 			}
314*e887ea33SDavid du Colombier 		}
315*e887ea33SDavid du Colombier 		if(l >= n)
316*e887ea33SDavid du Colombier 			continue;
317*e887ea33SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
318*e887ea33SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
319*e887ea33SDavid du Colombier 				if(buf.dbuf[j]) {
320*e887ea33SDavid du Colombier 					print("%P\n", p);
321*e887ea33SDavid du Colombier 					diag("multiple initialization");
322*e887ea33SDavid du Colombier 					break;
323*e887ea33SDavid du Colombier 				}
324*e887ea33SDavid du Colombier 		}
325*e887ea33SDavid du Colombier 		switch(p->to.type) {
326*e887ea33SDavid du Colombier 		case D_FCONST:
327*e887ea33SDavid du Colombier 			switch(c) {
328*e887ea33SDavid du Colombier 			default:
329*e887ea33SDavid du Colombier 			case 4:
330*e887ea33SDavid du Colombier 				fl = ieeedtof(&p->to.ieee);
331*e887ea33SDavid du Colombier 				cast = (uchar*)&fl;
332*e887ea33SDavid du Colombier 				if(debug['a'] && i == 0) {
333*e887ea33SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
334*e887ea33SDavid du Colombier 					for(j=0; j<c; j++)
335*e887ea33SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[fnuxi4[j]]);
336*e887ea33SDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
337*e887ea33SDavid du Colombier 				}
338*e887ea33SDavid du Colombier 				for(; i<c; i++) {
339*e887ea33SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi4[i]];
340*e887ea33SDavid du Colombier 					l++;
341*e887ea33SDavid du Colombier 				}
342*e887ea33SDavid du Colombier 				break;
343*e887ea33SDavid du Colombier 			case 8:
344*e887ea33SDavid du Colombier 				cast = (uchar*)&p->to.ieee;
345*e887ea33SDavid du Colombier 				if(debug['a'] && i == 0) {
346*e887ea33SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
347*e887ea33SDavid du Colombier 					for(j=0; j<c; j++)
348*e887ea33SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[fnuxi8[j]]);
349*e887ea33SDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
350*e887ea33SDavid du Colombier 				}
351*e887ea33SDavid du Colombier 				for(; i<c; i++) {
352*e887ea33SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
353*e887ea33SDavid du Colombier 					l++;
354*e887ea33SDavid du Colombier 				}
355*e887ea33SDavid du Colombier 				break;
356*e887ea33SDavid du Colombier 			}
357*e887ea33SDavid du Colombier 			break;
358*e887ea33SDavid du Colombier 
359*e887ea33SDavid du Colombier 		case D_SCONST:
360*e887ea33SDavid du Colombier 			if(debug['a'] && i == 0) {
361*e887ea33SDavid du Colombier 				Bprint(&bso, pcstr, l+s+INITDAT);
362*e887ea33SDavid du Colombier 				for(j=0; j<c; j++)
363*e887ea33SDavid du Colombier 					Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
364*e887ea33SDavid du Colombier 				Bprint(&bso, "\t%P\n", curp);
365*e887ea33SDavid du Colombier 			}
366*e887ea33SDavid du Colombier 			for(; i<c; i++) {
367*e887ea33SDavid du Colombier 				buf.dbuf[l] = p->to.scon[i];
368*e887ea33SDavid du Colombier 				l++;
369*e887ea33SDavid du Colombier 			}
370*e887ea33SDavid du Colombier 			break;
371*e887ea33SDavid du Colombier 		default:
372*e887ea33SDavid du Colombier 			o = p->to.offset;
373*e887ea33SDavid du Colombier 			if(p->to.type == D_ADDR) {
374*e887ea33SDavid du Colombier 				if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
375*e887ea33SDavid du Colombier 					diag("DADDR type%P", p);
376*e887ea33SDavid du Colombier 				if(p->to.sym) {
377*e887ea33SDavid du Colombier 					if(p->to.sym->type == SUNDEF)
378*e887ea33SDavid du Colombier 						ckoff(p->to.sym, o);
379*e887ea33SDavid du Colombier 					o += p->to.sym->value;
380*e887ea33SDavid du Colombier 					if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF)
381*e887ea33SDavid du Colombier 						o += INITDAT;
382*e887ea33SDavid du Colombier 					if(dlm)
383*e887ea33SDavid du Colombier 						dynreloc(p->to.sym, l+s+INITDAT, 1);
384*e887ea33SDavid du Colombier 				}
385*e887ea33SDavid du Colombier 			}
386*e887ea33SDavid du Colombier 			fl = o;
387*e887ea33SDavid du Colombier 			cast = (uchar*)&fl;
388*e887ea33SDavid du Colombier 			switch(c) {
389*e887ea33SDavid du Colombier 			default:
390*e887ea33SDavid du Colombier 				diag("bad nuxi %d %d\n%P", c, i, curp);
391*e887ea33SDavid du Colombier 				break;
392*e887ea33SDavid du Colombier 			case 1:
393*e887ea33SDavid du Colombier 				if(debug['a'] && i == 0) {
394*e887ea33SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
395*e887ea33SDavid du Colombier 					for(j=0; j<c; j++)
396*e887ea33SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi1[j]]);
397*e887ea33SDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
398*e887ea33SDavid du Colombier 				}
399*e887ea33SDavid du Colombier 				for(; i<c; i++) {
400*e887ea33SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
401*e887ea33SDavid du Colombier 					l++;
402*e887ea33SDavid du Colombier 				}
403*e887ea33SDavid du Colombier 				break;
404*e887ea33SDavid du Colombier 			case 2:
405*e887ea33SDavid du Colombier 				if(debug['a'] && i == 0) {
406*e887ea33SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
407*e887ea33SDavid du Colombier 					for(j=0; j<c; j++)
408*e887ea33SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi2[j]]);
409*e887ea33SDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
410*e887ea33SDavid du Colombier 				}
411*e887ea33SDavid du Colombier 				for(; i<c; i++) {
412*e887ea33SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
413*e887ea33SDavid du Colombier 					l++;
414*e887ea33SDavid du Colombier 				}
415*e887ea33SDavid du Colombier 				break;
416*e887ea33SDavid du Colombier 			case 4:
417*e887ea33SDavid du Colombier 				if(debug['a'] && i == 0) {
418*e887ea33SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
419*e887ea33SDavid du Colombier 					for(j=0; j<c; j++)
420*e887ea33SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi4[j]]);
421*e887ea33SDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
422*e887ea33SDavid du Colombier 				}
423*e887ea33SDavid du Colombier 				for(; i<c; i++) {
424*e887ea33SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
425*e887ea33SDavid du Colombier 					l++;
426*e887ea33SDavid du Colombier 				}
427*e887ea33SDavid du Colombier 				break;
428*e887ea33SDavid du Colombier 			case 8:
429*e887ea33SDavid du Colombier 				cast = (uchar*)&o;
430*e887ea33SDavid du Colombier 				if(debug['a'] && i == 0) {
431*e887ea33SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
432*e887ea33SDavid du Colombier 					for(j=0; j<c; j++)
433*e887ea33SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi8[j]]);
434*e887ea33SDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
435*e887ea33SDavid du Colombier 				}
436*e887ea33SDavid du Colombier 				for(; i<c; i++) {
437*e887ea33SDavid du Colombier 					buf.dbuf[l] = cast[inuxi8[i]];
438*e887ea33SDavid du Colombier 					l++;
439*e887ea33SDavid du Colombier 				}
440*e887ea33SDavid du Colombier 				break;
441*e887ea33SDavid du Colombier 			}
442*e887ea33SDavid du Colombier 			break;
443*e887ea33SDavid du Colombier 		}
444*e887ea33SDavid du Colombier 	}
445*e887ea33SDavid du Colombier 	write(cout, buf.dbuf, n);
446*e887ea33SDavid du Colombier }
447*e887ea33SDavid du Colombier 
448*e887ea33SDavid du Colombier vlong
449*e887ea33SDavid du Colombier rnd(vlong v, vlong r)
450*e887ea33SDavid du Colombier {
451*e887ea33SDavid du Colombier 	vlong c;
452*e887ea33SDavid du Colombier 
453*e887ea33SDavid du Colombier 	if(r <= 0)
454*e887ea33SDavid du Colombier 		return v;
455*e887ea33SDavid du Colombier 	v += r - 1;
456*e887ea33SDavid du Colombier 	c = v % r;
457*e887ea33SDavid du Colombier 	if(c < 0)
458*e887ea33SDavid du Colombier 		c += r;
459*e887ea33SDavid du Colombier 	v -= c;
460*e887ea33SDavid du Colombier 	return v;
461*e887ea33SDavid du Colombier }
462