xref: /plan9/sys/src/cmd/8l/asm.c (revision 6b6b9ac8b0b103b1e30e4d019522a78c950fce74)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier #define	Dbufslop	100
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier long
63e12c5d1SDavid du Colombier entryvalue(void)
73e12c5d1SDavid du Colombier {
83e12c5d1SDavid du Colombier 	char *a;
93e12c5d1SDavid du Colombier 	Sym *s;
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier 	a = INITENTRY;
123e12c5d1SDavid du Colombier 	if(*a >= '0' && *a <= '9')
133e12c5d1SDavid du Colombier 		return atolwhex(a);
143e12c5d1SDavid du Colombier 	s = lookup(a, 0);
153e12c5d1SDavid du Colombier 	if(s->type == 0)
163e12c5d1SDavid du Colombier 		return INITTEXT;
179a747e4fSDavid du Colombier 	switch(s->type) {
189a747e4fSDavid du Colombier 	case STEXT:
199a747e4fSDavid du Colombier 		break;
209a747e4fSDavid du Colombier 	case SDATA:
219a747e4fSDavid du Colombier 		if(reloc)
229a747e4fSDavid du Colombier 			return s->value+INITDAT;
239a747e4fSDavid du Colombier 	default:
243e12c5d1SDavid du Colombier 		diag("entry not text: %s", s->name);
259a747e4fSDavid du Colombier 	}
263e12c5d1SDavid du Colombier 	return s->value;
273e12c5d1SDavid du Colombier }
2859cc4ca5SDavid du Colombier void
2959cc4ca5SDavid du Colombier cput(int c)
3059cc4ca5SDavid du Colombier {
3159cc4ca5SDavid du Colombier 	*cbp = c;
3259cc4ca5SDavid du Colombier 	cbp++;
3359cc4ca5SDavid du Colombier 	cbc--;
3459cc4ca5SDavid du Colombier 	if(cbc <= 0)
3559cc4ca5SDavid du Colombier 		cflush();
3659cc4ca5SDavid du Colombier }
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier void
39219b2ee8SDavid du Colombier wput(ushort w)
40219b2ee8SDavid du Colombier {
4159cc4ca5SDavid du Colombier 	cput(w);
4259cc4ca5SDavid du Colombier 	cput(w>>8);
43219b2ee8SDavid du Colombier }
44219b2ee8SDavid du Colombier 
45219b2ee8SDavid du Colombier void
463e12c5d1SDavid du Colombier asmb(void)
473e12c5d1SDavid du Colombier {
483e12c5d1SDavid du Colombier 	Prog *p;
499a747e4fSDavid du Colombier 	long v, magic;
503e12c5d1SDavid du Colombier 	int a;
513e12c5d1SDavid du Colombier 	uchar *op1;
523e12c5d1SDavid du Colombier 
533e12c5d1SDavid du Colombier 	if(debug['v'])
543e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f asmb\n", cputime());
553e12c5d1SDavid du Colombier 	Bflush(&bso);
563e12c5d1SDavid du Colombier 
573e12c5d1SDavid du Colombier 	seek(cout, HEADR, 0);
583e12c5d1SDavid du Colombier 	pc = INITTEXT;
593e12c5d1SDavid du Colombier 	curp = firstp;
603e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
613e12c5d1SDavid du Colombier 		if(p->as == ATEXT)
623e12c5d1SDavid du Colombier 			curtext = p;
633e12c5d1SDavid du Colombier 		if(p->pc != pc) {
643e12c5d1SDavid du Colombier 			if(!debug['a'])
653e12c5d1SDavid du Colombier 				print("%P\n", curp);
66*6b6b9ac8SDavid du Colombier 			diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME);
673e12c5d1SDavid du Colombier 			pc = p->pc;
683e12c5d1SDavid du Colombier 		}
693e12c5d1SDavid du Colombier 		curp = p;
703e12c5d1SDavid du Colombier 		asmins(p);
713e12c5d1SDavid du Colombier 		if(cbc < sizeof(and))
723e12c5d1SDavid du Colombier 			cflush();
733e12c5d1SDavid du Colombier 		a = (andptr - and);
743e12c5d1SDavid du Colombier 		if(debug['a']) {
753e12c5d1SDavid du Colombier 			Bprint(&bso, pcstr, pc);
763e12c5d1SDavid du Colombier 			for(op1 = and; op1 < andptr; op1++)
773e12c5d1SDavid du Colombier 				Bprint(&bso, "%.2ux", *op1 & 0xff);
789a747e4fSDavid du Colombier 			Bprint(&bso, "\t%P\n", curp);
799a747e4fSDavid du Colombier 		}
809a747e4fSDavid du Colombier 		if(reloc) {
819a747e4fSDavid du Colombier 			if(p->as == ATEXT)
829a747e4fSDavid du Colombier 				reloca = nil;
839a747e4fSDavid du Colombier 			else if(reloca != nil)
84*6b6b9ac8SDavid du Colombier 				diag("reloc failure: %P", curp);
853e12c5d1SDavid du Colombier 		}
863e12c5d1SDavid du Colombier 		memmove(cbp, and, a);
873e12c5d1SDavid du Colombier 		cbp += a;
883e12c5d1SDavid du Colombier 		pc += a;
893e12c5d1SDavid du Colombier 		cbc -= a;
903e12c5d1SDavid du Colombier 	}
913e12c5d1SDavid du Colombier 	cflush();
923e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
933e12c5d1SDavid du Colombier 	default:
94*6b6b9ac8SDavid du Colombier 		diag("unknown header type %d", HEADTYPE);
953e12c5d1SDavid du Colombier 	case 0:
963e12c5d1SDavid du Colombier 		seek(cout, rnd(HEADR+textsize, 8192), 0);
973e12c5d1SDavid du Colombier 		break;
983e12c5d1SDavid du Colombier 	case 1:
993e12c5d1SDavid du Colombier 		textsize = rnd(HEADR+textsize, 4096)-HEADR;
1003e12c5d1SDavid du Colombier 		seek(cout, textsize+HEADR, 0);
1013e12c5d1SDavid du Colombier 		break;
1023e12c5d1SDavid du Colombier 	case 2:
1033e12c5d1SDavid du Colombier 		seek(cout, HEADR+textsize, 0);
1043e12c5d1SDavid du Colombier 		break;
1053e12c5d1SDavid du Colombier 	case 3:
106219b2ee8SDavid du Colombier 	case 4:
1073e12c5d1SDavid du Colombier 		seek(cout, HEADR+rnd(textsize, INITRND), 0);
1083e12c5d1SDavid du Colombier 		break;
1093e12c5d1SDavid du Colombier 	}
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier 	if(debug['v'])
1123e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f datblk\n", cputime());
1133e12c5d1SDavid du Colombier 	Bflush(&bso);
1143e12c5d1SDavid du Colombier 	for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
1153e12c5d1SDavid du Colombier 		if(datsize-v > sizeof(buf)-Dbufslop)
1163e12c5d1SDavid du Colombier 			datblk(v, sizeof(buf)-Dbufslop);
1173e12c5d1SDavid du Colombier 		else
1183e12c5d1SDavid du Colombier 			datblk(v, datsize-v);
1193e12c5d1SDavid du Colombier 	}
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier 	symsize = 0;
1223e12c5d1SDavid du Colombier 	spsize = 0;
1233e12c5d1SDavid du Colombier 	lcsize = 0;
1243e12c5d1SDavid du Colombier 	if(!debug['s']) {
1253e12c5d1SDavid du Colombier 		if(debug['v'])
1263e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
1273e12c5d1SDavid du Colombier 		Bflush(&bso);
1283e12c5d1SDavid du Colombier 		switch(HEADTYPE) {
1293e12c5d1SDavid du Colombier 		default:
1303e12c5d1SDavid du Colombier 		case 0:
1313e12c5d1SDavid du Colombier 			seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
1323e12c5d1SDavid du Colombier 			break;
1333e12c5d1SDavid du Colombier 		case 1:
1343e12c5d1SDavid du Colombier 			seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
1353e12c5d1SDavid du Colombier 			break;
1363e12c5d1SDavid du Colombier 		case 2:
1373e12c5d1SDavid du Colombier 			seek(cout, HEADR+textsize+datsize, 0);
1383e12c5d1SDavid du Colombier 			break;
1393e12c5d1SDavid du Colombier 		case 3:
140219b2ee8SDavid du Colombier 		case 4:
1413e12c5d1SDavid du Colombier 			debug['s'] = 1;
1423e12c5d1SDavid du Colombier 			break;
1433e12c5d1SDavid du Colombier 		}
1443e12c5d1SDavid du Colombier 		if(!debug['s'])
1453e12c5d1SDavid du Colombier 			asmsym();
1463e12c5d1SDavid du Colombier 		if(debug['v'])
1473e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f sp\n", cputime());
1483e12c5d1SDavid du Colombier 		Bflush(&bso);
1493e12c5d1SDavid du Colombier 		if(debug['v'])
1503e12c5d1SDavid du Colombier 			Bprint(&bso, "%5.2f pc\n", cputime());
1513e12c5d1SDavid du Colombier 		Bflush(&bso);
1523e12c5d1SDavid du Colombier 		if(!debug['s'])
1533e12c5d1SDavid du Colombier 			asmlc();
1543e12c5d1SDavid du Colombier 		cflush();
1553e12c5d1SDavid du Colombier 	}
1563e12c5d1SDavid du Colombier 	if(debug['v'])
1573e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f headr\n", cputime());
1583e12c5d1SDavid du Colombier 	Bflush(&bso);
1593e12c5d1SDavid du Colombier 	seek(cout, 0L, 0);
1603e12c5d1SDavid du Colombier 	switch(HEADTYPE) {
1613e12c5d1SDavid du Colombier 	default:
1623e12c5d1SDavid du Colombier 	case 0:	/* garbage */
1633e12c5d1SDavid du Colombier 		lput(0x160L<<16);		/* magic and sections */
1643e12c5d1SDavid du Colombier 		lput(0L);			/* time and date */
1653e12c5d1SDavid du Colombier 		lput(rnd(HEADR+textsize, 4096)+datsize);
1663e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
1673e12c5d1SDavid du Colombier 		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
1683e12c5d1SDavid du Colombier 		lput((0413<<16)|0437L);		/* magic and version */
1693e12c5d1SDavid du Colombier 		lput(rnd(HEADR+textsize, 4096));	/* sizes */
1703e12c5d1SDavid du Colombier 		lput(datsize);
1713e12c5d1SDavid du Colombier 		lput(bsssize);
1723e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
1733e12c5d1SDavid du Colombier 		lput(INITTEXT-HEADR);		/* va of base of text */
1743e12c5d1SDavid du Colombier 		lput(INITDAT);			/* va of base of data */
1753e12c5d1SDavid du Colombier 		lput(INITDAT+datsize);		/* va of base of bss */
1763e12c5d1SDavid du Colombier 		lput(~0L);			/* gp reg mask */
1773e12c5d1SDavid du Colombier 		lput(0L);
1783e12c5d1SDavid du Colombier 		lput(0L);
1793e12c5d1SDavid du Colombier 		lput(0L);
1803e12c5d1SDavid du Colombier 		lput(0L);
1813e12c5d1SDavid du Colombier 		lput(~0L);			/* gp value ?? */
1823e12c5d1SDavid du Colombier 		break;
1833e12c5d1SDavid du Colombier 		lputl(0);			/* x */
1843e12c5d1SDavid du Colombier 	case 1:	/* unix coff */
1853e12c5d1SDavid du Colombier 		/*
1863e12c5d1SDavid du Colombier 		 * file header
1873e12c5d1SDavid du Colombier 		 */
1883e12c5d1SDavid du Colombier 		lputl(0x0004014c);		/* 4 sections, magic */
1893e12c5d1SDavid du Colombier 		lputl(0);			/* unix time stamp */
1903e12c5d1SDavid du Colombier 		lputl(0);			/* symbol table */
1913e12c5d1SDavid du Colombier 		lputl(0);			/* nsyms */
1923e12c5d1SDavid du Colombier 		lputl(0x0003001c);		/* flags, sizeof a.out header */
1933e12c5d1SDavid du Colombier 		/*
1943e12c5d1SDavid du Colombier 		 * a.out header
1953e12c5d1SDavid du Colombier 		 */
1963e12c5d1SDavid du Colombier 		lputl(0x10b);			/* magic, version stamp */
1973e12c5d1SDavid du Colombier 		lputl(rnd(textsize, INITRND));	/* text sizes */
1983e12c5d1SDavid du Colombier 		lputl(datsize);			/* data sizes */
1993e12c5d1SDavid du Colombier 		lputl(bsssize);			/* bss sizes */
2003e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
2013e12c5d1SDavid du Colombier 		lputl(INITTEXT);		/* text start */
2023e12c5d1SDavid du Colombier 		lputl(INITDAT);			/* data start */
2033e12c5d1SDavid du Colombier 		/*
2043e12c5d1SDavid du Colombier 		 * text section header
2053e12c5d1SDavid du Colombier 		 */
2063e12c5d1SDavid du Colombier 		s8put(".text");
2073e12c5d1SDavid du Colombier 		lputl(HEADR);			/* pa */
2083e12c5d1SDavid du Colombier 		lputl(HEADR);			/* va */
2093e12c5d1SDavid du Colombier 		lputl(textsize);		/* text size */
2103e12c5d1SDavid du Colombier 		lputl(HEADR);			/* file offset */
2113e12c5d1SDavid du Colombier 		lputl(0);			/* relocation */
2123e12c5d1SDavid du Colombier 		lputl(0);			/* line numbers */
2133e12c5d1SDavid du Colombier 		lputl(0);			/* relocation, line numbers */
2143e12c5d1SDavid du Colombier 		lputl(0x20);			/* flags text only */
2153e12c5d1SDavid du Colombier 		/*
2163e12c5d1SDavid du Colombier 		 * data section header
2173e12c5d1SDavid du Colombier 		 */
2183e12c5d1SDavid du Colombier 		s8put(".data");
2193e12c5d1SDavid du Colombier 		lputl(INITDAT);			/* pa */
2203e12c5d1SDavid du Colombier 		lputl(INITDAT);			/* va */
2213e12c5d1SDavid du Colombier 		lputl(datsize);			/* data size */
2223e12c5d1SDavid du Colombier 		lputl(HEADR+textsize);		/* file offset */
2233e12c5d1SDavid du Colombier 		lputl(0);			/* relocation */
2243e12c5d1SDavid du Colombier 		lputl(0);			/* line numbers */
2253e12c5d1SDavid du Colombier 		lputl(0);			/* relocation, line numbers */
2263e12c5d1SDavid du Colombier 		lputl(0x40);			/* flags data only */
2273e12c5d1SDavid du Colombier 		/*
2283e12c5d1SDavid du Colombier 		 * bss section header
2293e12c5d1SDavid du Colombier 		 */
2303e12c5d1SDavid du Colombier 		s8put(".bss");
2313e12c5d1SDavid du Colombier 		lputl(INITDAT+datsize);		/* pa */
2323e12c5d1SDavid du Colombier 		lputl(INITDAT+datsize);		/* va */
2333e12c5d1SDavid du Colombier 		lputl(bsssize);			/* bss size */
2343e12c5d1SDavid du Colombier 		lputl(0);			/* file offset */
2353e12c5d1SDavid du Colombier 		lputl(0);			/* relocation */
2363e12c5d1SDavid du Colombier 		lputl(0);			/* line numbers */
2373e12c5d1SDavid du Colombier 		lputl(0);			/* relocation, line numbers */
2383e12c5d1SDavid du Colombier 		lputl(0x80);			/* flags bss only */
2393e12c5d1SDavid du Colombier 		/*
2403e12c5d1SDavid du Colombier 		 * comment section header
2413e12c5d1SDavid du Colombier 		 */
2423e12c5d1SDavid du Colombier 		s8put(".comment");
2433e12c5d1SDavid du Colombier 		lputl(0);			/* pa */
2443e12c5d1SDavid du Colombier 		lputl(0);			/* va */
2453e12c5d1SDavid du Colombier 		lputl(symsize+lcsize);		/* comment size */
2463e12c5d1SDavid du Colombier 		lputl(HEADR+textsize+datsize);	/* file offset */
2473e12c5d1SDavid du Colombier 		lputl(HEADR+textsize+datsize);	/* offset of syms */
2483e12c5d1SDavid du Colombier 		lputl(HEADR+textsize+datsize+symsize);/* offset of line numbers */
2493e12c5d1SDavid du Colombier 		lputl(0);			/* relocation, line numbers */
2503e12c5d1SDavid du Colombier 		lputl(0x200);			/* flags comment only */
2513e12c5d1SDavid du Colombier 		break;
2523e12c5d1SDavid du Colombier 	case 2:	/* plan9 */
2539a747e4fSDavid du Colombier 		magic = 4*11*11+7;
2549a747e4fSDavid du Colombier 		if(reloc)
2559a747e4fSDavid du Colombier 			magic |= 0x80000000;
2569a747e4fSDavid du Colombier 		lput(magic);		/* magic */
2573e12c5d1SDavid du Colombier 		lput(textsize);			/* sizes */
2583e12c5d1SDavid du Colombier 		lput(datsize);
2593e12c5d1SDavid du Colombier 		lput(bsssize);
2603e12c5d1SDavid du Colombier 		lput(symsize);			/* nsyms */
2613e12c5d1SDavid du Colombier 		lput(entryvalue());		/* va of entry */
2623e12c5d1SDavid du Colombier 		lput(spsize);			/* sp offsets */
2633e12c5d1SDavid du Colombier 		lput(lcsize);			/* line offsets */
2643e12c5d1SDavid du Colombier 		break;
2653e12c5d1SDavid du Colombier 	case 3:
266219b2ee8SDavid du Colombier 		/* MS-DOS .COM */
267219b2ee8SDavid du Colombier 		break;
268219b2ee8SDavid du Colombier 	case 4:
269219b2ee8SDavid du Colombier 		/* fake MS-DOS .EXE */
270219b2ee8SDavid du Colombier 		v = rnd(HEADR+textsize, INITRND)+datsize;
271219b2ee8SDavid du Colombier 		wput(0x5A4D);			/* 'MZ' */
272219b2ee8SDavid du Colombier 		wput(v % 512);			/* bytes in last page */
273219b2ee8SDavid du Colombier 		wput(rnd(v, 512)/512);		/* total number of pages */
274219b2ee8SDavid du Colombier 		wput(0x0000);			/* number of reloc items */
275219b2ee8SDavid du Colombier 		v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);
276219b2ee8SDavid du Colombier 		wput(v/16);			/* size of header */
277219b2ee8SDavid du Colombier 		wput(0x0000);			/* minimum allocation */
278219b2ee8SDavid du Colombier 		wput(0xFFFF);			/* maximum allocation */
279219b2ee8SDavid du Colombier 		wput(0x0000);			/* initial ss value */
280219b2ee8SDavid du Colombier 		wput(0x0100);			/* initial sp value */
281219b2ee8SDavid du Colombier 		wput(0x0000);			/* complemented checksum */
282219b2ee8SDavid du Colombier 		v = entryvalue();
283219b2ee8SDavid du Colombier 		wput(v);			/* initial ip value (!) */
284219b2ee8SDavid du Colombier 		wput(0x0000);			/* initial cs value */
285219b2ee8SDavid du Colombier 		wput(0x0000);
286219b2ee8SDavid du Colombier 		wput(0x0000);
287219b2ee8SDavid du Colombier 		wput(0x003E);			/* reloc table offset */
288219b2ee8SDavid du Colombier 		wput(0x0000);			/* overlay number */
2893e12c5d1SDavid du Colombier 		break;
2903e12c5d1SDavid du Colombier 	}
2913e12c5d1SDavid du Colombier 	cflush();
2923e12c5d1SDavid du Colombier }
2933e12c5d1SDavid du Colombier 
2943e12c5d1SDavid du Colombier void
2953e12c5d1SDavid du Colombier lput(long l)
2963e12c5d1SDavid du Colombier {
29759cc4ca5SDavid du Colombier 	cput(l>>24);
29859cc4ca5SDavid du Colombier 	cput(l>>16);
29959cc4ca5SDavid du Colombier 	cput(l>>8);
30059cc4ca5SDavid du Colombier 	cput(l);
3013e12c5d1SDavid du Colombier }
3023e12c5d1SDavid du Colombier 
3033e12c5d1SDavid du Colombier void
3043e12c5d1SDavid du Colombier lputl(long l)
3053e12c5d1SDavid du Colombier {
30659cc4ca5SDavid du Colombier 	cput(l);
30759cc4ca5SDavid du Colombier 	cput(l>>8);
30859cc4ca5SDavid du Colombier 	cput(l>>16);
30959cc4ca5SDavid du Colombier 	cput(l>>24);
3103e12c5d1SDavid du Colombier }
3113e12c5d1SDavid du Colombier 
3123e12c5d1SDavid du Colombier void
3133e12c5d1SDavid du Colombier s8put(char *n)
3143e12c5d1SDavid du Colombier {
3153e12c5d1SDavid du Colombier 	char name[8];
3163e12c5d1SDavid du Colombier 	int i;
3173e12c5d1SDavid du Colombier 
3183e12c5d1SDavid du Colombier 	strncpy(name, n, sizeof(name));
3193e12c5d1SDavid du Colombier 	for(i=0; i<sizeof(name); i++)
32059cc4ca5SDavid du Colombier 		cput(name[i]);
3213e12c5d1SDavid du Colombier }
3223e12c5d1SDavid du Colombier 
3233e12c5d1SDavid du Colombier void
3243e12c5d1SDavid du Colombier cflush(void)
3253e12c5d1SDavid du Colombier {
3263e12c5d1SDavid du Colombier 	int n;
3273e12c5d1SDavid du Colombier 
3283e12c5d1SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
3293e12c5d1SDavid du Colombier 	if(n)
3303e12c5d1SDavid du Colombier 		write(cout, buf.cbuf, n);
3313e12c5d1SDavid du Colombier 	cbp = buf.cbuf;
3323e12c5d1SDavid du Colombier 	cbc = sizeof(buf.cbuf);
3333e12c5d1SDavid du Colombier }
3343e12c5d1SDavid du Colombier 
3353e12c5d1SDavid du Colombier void
3363e12c5d1SDavid du Colombier datblk(long s, long n)
3373e12c5d1SDavid du Colombier {
3383e12c5d1SDavid du Colombier 	Prog *p;
3393e12c5d1SDavid du Colombier 	char *cast;
3403e12c5d1SDavid du Colombier 	long l, fl, j;
3413e12c5d1SDavid du Colombier 	int i, c;
3423e12c5d1SDavid du Colombier 
3433e12c5d1SDavid du Colombier 	memset(buf.dbuf, 0, n+Dbufslop);
3443e12c5d1SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
3453e12c5d1SDavid du Colombier 		curp = p;
3463e12c5d1SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
3473e12c5d1SDavid du Colombier 		c = p->from.scale;
3483e12c5d1SDavid du Colombier 		i = 0;
3493e12c5d1SDavid du Colombier 		if(l < 0) {
3503e12c5d1SDavid du Colombier 			if(l+c <= 0)
3513e12c5d1SDavid du Colombier 				continue;
3523e12c5d1SDavid du Colombier 			while(l < 0) {
3533e12c5d1SDavid du Colombier 				l++;
3543e12c5d1SDavid du Colombier 				i++;
3553e12c5d1SDavid du Colombier 			}
3563e12c5d1SDavid du Colombier 		}
3573e12c5d1SDavid du Colombier 		if(l >= n)
3583e12c5d1SDavid du Colombier 			continue;
359219b2ee8SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
3603e12c5d1SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
3613e12c5d1SDavid du Colombier 				if(buf.dbuf[j]) {
3623e12c5d1SDavid du Colombier 					print("%P\n", p);
363*6b6b9ac8SDavid du Colombier 					diag("multiple initialization");
3643e12c5d1SDavid du Colombier 					break;
3653e12c5d1SDavid du Colombier 				}
366219b2ee8SDavid du Colombier 		}
3673e12c5d1SDavid du Colombier 		switch(p->to.type) {
3683e12c5d1SDavid du Colombier 		case D_FCONST:
3693e12c5d1SDavid du Colombier 			switch(c) {
3703e12c5d1SDavid du Colombier 			default:
3713e12c5d1SDavid du Colombier 			case 4:
3723e12c5d1SDavid du Colombier 				fl = ieeedtof(&p->to.ieee);
3733e12c5d1SDavid du Colombier 				cast = (char*)&fl;
3743e12c5d1SDavid du Colombier 				if(debug['a'] && i == 0) {
3753e12c5d1SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
3763e12c5d1SDavid du Colombier 					for(j=0; j<c; j++)
3773e12c5d1SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff);
3789a747e4fSDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
3793e12c5d1SDavid du Colombier 				}
3803e12c5d1SDavid du Colombier 				for(; i<c; i++) {
3813e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi4[i]];
3823e12c5d1SDavid du Colombier 					l++;
3833e12c5d1SDavid du Colombier 				}
3843e12c5d1SDavid du Colombier 				break;
3853e12c5d1SDavid du Colombier 			case 8:
3863e12c5d1SDavid du Colombier 				cast = (char*)&p->to.ieee;
3873e12c5d1SDavid du Colombier 				if(debug['a'] && i == 0) {
3883e12c5d1SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
3893e12c5d1SDavid du Colombier 					for(j=0; j<c; j++)
3903e12c5d1SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
3919a747e4fSDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
3923e12c5d1SDavid du Colombier 				}
3933e12c5d1SDavid du Colombier 				for(; i<c; i++) {
3943e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
3953e12c5d1SDavid du Colombier 					l++;
3963e12c5d1SDavid du Colombier 				}
3973e12c5d1SDavid du Colombier 				break;
3983e12c5d1SDavid du Colombier 			}
3993e12c5d1SDavid du Colombier 			break;
4003e12c5d1SDavid du Colombier 
4013e12c5d1SDavid du Colombier 		case D_SCONST:
4023e12c5d1SDavid du Colombier 			if(debug['a'] && i == 0) {
4033e12c5d1SDavid du Colombier 				Bprint(&bso, pcstr, l+s+INITDAT);
4043e12c5d1SDavid du Colombier 				for(j=0; j<c; j++)
4053e12c5d1SDavid du Colombier 					Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
4069a747e4fSDavid du Colombier 				Bprint(&bso, "\t%P\n", curp);
4073e12c5d1SDavid du Colombier 			}
4083e12c5d1SDavid du Colombier 			for(; i<c; i++) {
4093e12c5d1SDavid du Colombier 				buf.dbuf[l] = p->to.scon[i];
4103e12c5d1SDavid du Colombier 				l++;
4113e12c5d1SDavid du Colombier 			}
4123e12c5d1SDavid du Colombier 			break;
4133e12c5d1SDavid du Colombier 		default:
4143e12c5d1SDavid du Colombier 			fl = p->to.offset;
4153e12c5d1SDavid du Colombier 			if(p->to.type == D_ADDR) {
4163e12c5d1SDavid du Colombier 				if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
417*6b6b9ac8SDavid du Colombier 					diag("DADDR type%P", p);
4183e12c5d1SDavid du Colombier 				if(p->to.sym) {
4199a747e4fSDavid du Colombier 					if(reloc)
4209a747e4fSDavid du Colombier 						wreloc(p->to.sym, l+s+INITDAT);
4213e12c5d1SDavid du Colombier 					fl += p->to.sym->value;
4229a747e4fSDavid du Colombier 					if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF)
4233e12c5d1SDavid du Colombier 						fl += INITDAT;
4243e12c5d1SDavid du Colombier 				}
4253e12c5d1SDavid du Colombier 			}
4263e12c5d1SDavid du Colombier 			cast = (char*)&fl;
4273e12c5d1SDavid du Colombier 			switch(c) {
4283e12c5d1SDavid du Colombier 			default:
429*6b6b9ac8SDavid du Colombier 				diag("bad nuxi %d %d\n%P", c, i, curp);
4303e12c5d1SDavid du Colombier 				break;
4313e12c5d1SDavid du Colombier 			case 1:
4323e12c5d1SDavid du Colombier 				if(debug['a'] && i == 0) {
4333e12c5d1SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
4343e12c5d1SDavid du Colombier 					for(j=0; j<c; j++)
4353e12c5d1SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff);
4369a747e4fSDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
4373e12c5d1SDavid du Colombier 				}
4383e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4393e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
4403e12c5d1SDavid du Colombier 					l++;
4413e12c5d1SDavid du Colombier 				}
4423e12c5d1SDavid du Colombier 				break;
4433e12c5d1SDavid du Colombier 			case 2:
4443e12c5d1SDavid du Colombier 				if(debug['a'] && i == 0) {
4453e12c5d1SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
4463e12c5d1SDavid du Colombier 					for(j=0; j<c; j++)
4473e12c5d1SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff);
4489a747e4fSDavid du Colombier 					Bprint(&bso, "]\t%P\n", curp);
4493e12c5d1SDavid du Colombier 				}
4503e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4513e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
4523e12c5d1SDavid du Colombier 					l++;
4533e12c5d1SDavid du Colombier 				}
4543e12c5d1SDavid du Colombier 				break;
4553e12c5d1SDavid du Colombier 			case 4:
4563e12c5d1SDavid du Colombier 				if(debug['a'] && i == 0) {
4573e12c5d1SDavid du Colombier 					Bprint(&bso, pcstr, l+s+INITDAT);
4583e12c5d1SDavid du Colombier 					for(j=0; j<c; j++)
4593e12c5d1SDavid du Colombier 						Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff);
4609a747e4fSDavid du Colombier 					Bprint(&bso, "\t%P\n", curp);
4613e12c5d1SDavid du Colombier 				}
4623e12c5d1SDavid du Colombier 				for(; i<c; i++) {
4633e12c5d1SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
4643e12c5d1SDavid du Colombier 					l++;
4653e12c5d1SDavid du Colombier 				}
4663e12c5d1SDavid du Colombier 				break;
4673e12c5d1SDavid du Colombier 			}
4683e12c5d1SDavid du Colombier 			break;
4693e12c5d1SDavid du Colombier 		}
4703e12c5d1SDavid du Colombier 	}
4713e12c5d1SDavid du Colombier 	write(cout, buf.dbuf, n);
4723e12c5d1SDavid du Colombier }
4733e12c5d1SDavid du Colombier 
4743e12c5d1SDavid du Colombier long
4753e12c5d1SDavid du Colombier rnd(long v, long r)
4763e12c5d1SDavid du Colombier {
4773e12c5d1SDavid du Colombier 	long c;
4783e12c5d1SDavid du Colombier 
4793e12c5d1SDavid du Colombier 	if(r <= 0)
4803e12c5d1SDavid du Colombier 		return v;
4813e12c5d1SDavid du Colombier 	v += r - 1;
4823e12c5d1SDavid du Colombier 	c = v % r;
4833e12c5d1SDavid du Colombier 	if(c < 0)
4843e12c5d1SDavid du Colombier 		c += r;
4853e12c5d1SDavid du Colombier 	v -= c;
4863e12c5d1SDavid du Colombier 	return v;
4873e12c5d1SDavid du Colombier }
488