xref: /inferno-os/utils/ql/asm.c (revision 45a20ab721a513710138340faff3d59a31c3e01e)
174a4d8c2SCharles.Forsyth #include	"l.h"
274a4d8c2SCharles.Forsyth 
3647adfbcSforsyth #define JMPSZ	sizeof(u32int)		/* size of bootstrap jump section */
474a4d8c2SCharles.Forsyth 
574a4d8c2SCharles.Forsyth #define	LPUT(c)\
674a4d8c2SCharles.Forsyth 	{\
774a4d8c2SCharles.Forsyth 		cbp[0] = (c)>>24;\
874a4d8c2SCharles.Forsyth 		cbp[1] = (c)>>16;\
974a4d8c2SCharles.Forsyth 		cbp[2] = (c)>>8;\
1074a4d8c2SCharles.Forsyth 		cbp[3] = (c);\
1174a4d8c2SCharles.Forsyth 		cbp += 4;\
1274a4d8c2SCharles.Forsyth 		cbc -= 4;\
1374a4d8c2SCharles.Forsyth 		if(cbc <= 0)\
1474a4d8c2SCharles.Forsyth 			cflush();\
1574a4d8c2SCharles.Forsyth 	}
1674a4d8c2SCharles.Forsyth 
1774a4d8c2SCharles.Forsyth #define	CPUT(c)\
1874a4d8c2SCharles.Forsyth 	{\
1974a4d8c2SCharles.Forsyth 		cbp[0] = (c);\
2074a4d8c2SCharles.Forsyth 		cbp++;\
2174a4d8c2SCharles.Forsyth 		cbc--;\
2274a4d8c2SCharles.Forsyth 		if(cbc <= 0)\
2374a4d8c2SCharles.Forsyth 			cflush();\
2474a4d8c2SCharles.Forsyth 	}
2574a4d8c2SCharles.Forsyth 
2674a4d8c2SCharles.Forsyth void	strnput(char*, int);
2774a4d8c2SCharles.Forsyth 
2874a4d8c2SCharles.Forsyth long
entryvalue(void)2974a4d8c2SCharles.Forsyth entryvalue(void)
3074a4d8c2SCharles.Forsyth {
3174a4d8c2SCharles.Forsyth 	char *a;
3274a4d8c2SCharles.Forsyth 	Sym *s;
3374a4d8c2SCharles.Forsyth 
3474a4d8c2SCharles.Forsyth 	a = INITENTRY;
3574a4d8c2SCharles.Forsyth 	if(*a >= '0' && *a <= '9')
3674a4d8c2SCharles.Forsyth 		return atolwhex(a);
3774a4d8c2SCharles.Forsyth 	s = lookup(a, 0);
3874a4d8c2SCharles.Forsyth 	if(s->type == 0)
3974a4d8c2SCharles.Forsyth 		return INITTEXT;
4074a4d8c2SCharles.Forsyth 	if(dlm && s->type == SDATA)
4174a4d8c2SCharles.Forsyth 		return s->value+INITDAT;
4274a4d8c2SCharles.Forsyth 	if(s->type != STEXT && s->type != SLEAF)
4374a4d8c2SCharles.Forsyth 		diag("entry not text: %s", s->name);
4474a4d8c2SCharles.Forsyth 	return s->value;
4574a4d8c2SCharles.Forsyth }
4674a4d8c2SCharles.Forsyth 
47*45a20ab7Sforsyth static void
elf32jmp(Putl putl)48*45a20ab7Sforsyth elf32jmp(Putl putl)
49*45a20ab7Sforsyth {
50*45a20ab7Sforsyth 	/* describe a tiny text section at end with jmp to start; see below */
51*45a20ab7Sforsyth 	elf32phdr(putl, PT_LOAD, HEADR+textsize-JMPSZ, 0xFFFFFFFC, 0xFFFFFFFC,
52*45a20ab7Sforsyth 		JMPSZ, JMPSZ, R|X, 0);	/* text */
53*45a20ab7Sforsyth }
54*45a20ab7Sforsyth 
5574a4d8c2SCharles.Forsyth void
asmb(void)5674a4d8c2SCharles.Forsyth asmb(void)
5774a4d8c2SCharles.Forsyth {
5874a4d8c2SCharles.Forsyth 	Prog *p;
5974a4d8c2SCharles.Forsyth 	long t;
6074a4d8c2SCharles.Forsyth 	Optab *o;
61647adfbcSforsyth 	long prevpc;
6274a4d8c2SCharles.Forsyth 
6374a4d8c2SCharles.Forsyth 	if(debug['v'])
6474a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f asm\n", cputime());
6574a4d8c2SCharles.Forsyth 	Bflush(&bso);
66647adfbcSforsyth 
67647adfbcSforsyth 	/* emit text segment */
6874a4d8c2SCharles.Forsyth 	seek(cout, HEADR, 0);
69647adfbcSforsyth 	prevpc = pc = INITTEXT;
7074a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
7174a4d8c2SCharles.Forsyth 		if(p->as == ATEXT) {
7274a4d8c2SCharles.Forsyth 			curtext = p;
7374a4d8c2SCharles.Forsyth 			autosize = p->to.offset + 4;
7474a4d8c2SCharles.Forsyth 			if(p->from3.type == D_CONST) {
7574a4d8c2SCharles.Forsyth 				for(; pc < p->pc; pc++)
7674a4d8c2SCharles.Forsyth 					CPUT(0);
7774a4d8c2SCharles.Forsyth 			}
7874a4d8c2SCharles.Forsyth 		}
7974a4d8c2SCharles.Forsyth 		if(p->pc != pc) {
8074a4d8c2SCharles.Forsyth 			diag("phase error %lux sb %lux",
8174a4d8c2SCharles.Forsyth 				p->pc, pc);
8274a4d8c2SCharles.Forsyth 			if(!debug['a'])
8374a4d8c2SCharles.Forsyth 				prasm(curp);
8474a4d8c2SCharles.Forsyth 			pc = p->pc;
8574a4d8c2SCharles.Forsyth 		}
8674a4d8c2SCharles.Forsyth 		curp = p;
8774a4d8c2SCharles.Forsyth 		o = oplook(p);	/* could probably avoid this call */
8874a4d8c2SCharles.Forsyth 		if(asmout(p, o, 0)) {
8974a4d8c2SCharles.Forsyth 			p = p->link;
9074a4d8c2SCharles.Forsyth 			pc += 4;
9174a4d8c2SCharles.Forsyth 		}
9274a4d8c2SCharles.Forsyth 		pc += o->size;
93647adfbcSforsyth 		if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
94647adfbcSforsyth 			char *tn;
95647adfbcSforsyth 
96*45a20ab7Sforsyth 			tn = "??none??";
97647adfbcSforsyth 			if(curtext != P && curtext->from.sym != S)
98647adfbcSforsyth 				tn = curtext->from.sym->name;
99647adfbcSforsyth 			Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
10074a4d8c2SCharles.Forsyth 		}
101647adfbcSforsyth 		prevpc = pc;
102647adfbcSforsyth 	}
103647adfbcSforsyth 
10474a4d8c2SCharles.Forsyth 	if(debug['a'])
10574a4d8c2SCharles.Forsyth 		Bprint(&bso, "\n");
10674a4d8c2SCharles.Forsyth 	Bflush(&bso);
10774a4d8c2SCharles.Forsyth 	cflush();
10874a4d8c2SCharles.Forsyth 
109647adfbcSforsyth 	/* emit data segment */
11074a4d8c2SCharles.Forsyth 	curtext = P;
11174a4d8c2SCharles.Forsyth 	switch(HEADTYPE) {
112647adfbcSforsyth 	case 6:
113*45a20ab7Sforsyth 		/*
114*45a20ab7Sforsyth 		 * but first, for virtex 4, inject a jmp instruction after
115*45a20ab7Sforsyth 		 * other text: branch to absolute entry address (0xfffe2100).
116*45a20ab7Sforsyth 		 */
117*45a20ab7Sforsyth 		lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
118647adfbcSforsyth 		textsize += JMPSZ;
119*45a20ab7Sforsyth 		cflush();
120647adfbcSforsyth 		/* fall through */
12174a4d8c2SCharles.Forsyth 	case 0:
12274a4d8c2SCharles.Forsyth 	case 1:
12374a4d8c2SCharles.Forsyth 	case 2:
12474a4d8c2SCharles.Forsyth 	case 5:
12574a4d8c2SCharles.Forsyth 		seek(cout, HEADR+textsize, 0);
12674a4d8c2SCharles.Forsyth 		break;
12774a4d8c2SCharles.Forsyth 	case 3:
12874a4d8c2SCharles.Forsyth 		seek(cout, rnd(HEADR+textsize, 4), 0);
12974a4d8c2SCharles.Forsyth 		break;
13074a4d8c2SCharles.Forsyth 	case 4:
13174a4d8c2SCharles.Forsyth 		seek(cout, rnd(HEADR+textsize, 4096), 0);
13274a4d8c2SCharles.Forsyth 		break;
13374a4d8c2SCharles.Forsyth 	}
13474a4d8c2SCharles.Forsyth 
13574a4d8c2SCharles.Forsyth 	if(dlm){
13674a4d8c2SCharles.Forsyth 		char buf[8];
13774a4d8c2SCharles.Forsyth 
13874a4d8c2SCharles.Forsyth 		write(cout, buf, INITDAT-textsize);
13974a4d8c2SCharles.Forsyth 		textsize = INITDAT;
14074a4d8c2SCharles.Forsyth 	}
14174a4d8c2SCharles.Forsyth 
14274a4d8c2SCharles.Forsyth 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
14374a4d8c2SCharles.Forsyth 		if(datsize-t > sizeof(buf)-100)
14474a4d8c2SCharles.Forsyth 			datblk(t, sizeof(buf)-100);
14574a4d8c2SCharles.Forsyth 		else
14674a4d8c2SCharles.Forsyth 			datblk(t, datsize-t);
14774a4d8c2SCharles.Forsyth 	}
14874a4d8c2SCharles.Forsyth 
14974a4d8c2SCharles.Forsyth 	symsize = 0;
15074a4d8c2SCharles.Forsyth 	lcsize = 0;
15174a4d8c2SCharles.Forsyth 	if(!debug['s']) {
15274a4d8c2SCharles.Forsyth 		if(debug['v'])
15374a4d8c2SCharles.Forsyth 			Bprint(&bso, "%5.2f sym\n", cputime());
15474a4d8c2SCharles.Forsyth 		Bflush(&bso);
15574a4d8c2SCharles.Forsyth 		switch(HEADTYPE) {
15674a4d8c2SCharles.Forsyth 		case 0:
15774a4d8c2SCharles.Forsyth 		case 1:
15874a4d8c2SCharles.Forsyth 		case 2:
15974a4d8c2SCharles.Forsyth 		case 5:
160647adfbcSforsyth 		case 6:
16174a4d8c2SCharles.Forsyth 			seek(cout, HEADR+textsize+datsize, 0);
16274a4d8c2SCharles.Forsyth 			break;
16374a4d8c2SCharles.Forsyth 		case 3:
16474a4d8c2SCharles.Forsyth 			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
16574a4d8c2SCharles.Forsyth 			break;
16674a4d8c2SCharles.Forsyth 		case 4:
16774a4d8c2SCharles.Forsyth 			seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
16874a4d8c2SCharles.Forsyth 			break;
16974a4d8c2SCharles.Forsyth 		}
17074a4d8c2SCharles.Forsyth 		if(!debug['s'])
17174a4d8c2SCharles.Forsyth 			asmsym();
17274a4d8c2SCharles.Forsyth 		if(debug['v'])
17374a4d8c2SCharles.Forsyth 			Bprint(&bso, "%5.2f sp\n", cputime());
17474a4d8c2SCharles.Forsyth 		Bflush(&bso);
17574a4d8c2SCharles.Forsyth 		if(!debug['s'])
17674a4d8c2SCharles.Forsyth 			asmlc();
17774a4d8c2SCharles.Forsyth 		if(dlm)
17874a4d8c2SCharles.Forsyth 			asmdyn();
17974a4d8c2SCharles.Forsyth 		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */
18074a4d8c2SCharles.Forsyth 			if((symsize+lcsize) & 1)
18174a4d8c2SCharles.Forsyth 				CPUT(0);
18274a4d8c2SCharles.Forsyth 		cflush();
18374a4d8c2SCharles.Forsyth 	}
18474a4d8c2SCharles.Forsyth 	else if(dlm){
18574a4d8c2SCharles.Forsyth 		asmdyn();
18674a4d8c2SCharles.Forsyth 		cflush();
18774a4d8c2SCharles.Forsyth 	}
18874a4d8c2SCharles.Forsyth 
189647adfbcSforsyth 	/* back up and write the header */
19074a4d8c2SCharles.Forsyth 	seek(cout, 0L, 0);
19174a4d8c2SCharles.Forsyth 	switch(HEADTYPE) {
19274a4d8c2SCharles.Forsyth 	case 0:
19374a4d8c2SCharles.Forsyth 		lput(0x1030107);		/* magic and sections */
19474a4d8c2SCharles.Forsyth 		lput(textsize);			/* sizes */
19574a4d8c2SCharles.Forsyth 		lput(datsize);
19674a4d8c2SCharles.Forsyth 		lput(bsssize);
19774a4d8c2SCharles.Forsyth 		lput(symsize);			/* nsyms */
19874a4d8c2SCharles.Forsyth 		lput(entryvalue());		/* va of entry */
19974a4d8c2SCharles.Forsyth 		lput(0L);
20074a4d8c2SCharles.Forsyth 		lput(lcsize);
20174a4d8c2SCharles.Forsyth 		break;
20274a4d8c2SCharles.Forsyth 	case 1:
20374a4d8c2SCharles.Forsyth 		lput(0x4a6f7921);		/* Joy! */
20474a4d8c2SCharles.Forsyth 		lput(0x70656666);		/* peff */
20574a4d8c2SCharles.Forsyth 		lput(0x70777063);		/* pwpc */
20674a4d8c2SCharles.Forsyth 		lput(1);
20774a4d8c2SCharles.Forsyth 		lput(0);
20874a4d8c2SCharles.Forsyth 		lput(0);
20974a4d8c2SCharles.Forsyth 		lput(0);
21074a4d8c2SCharles.Forsyth 		lput(0);
21174a4d8c2SCharles.Forsyth 		lput(0x30002);			/*YY*/
21274a4d8c2SCharles.Forsyth 		lput(0);
21374a4d8c2SCharles.Forsyth 		lput(~0);
21474a4d8c2SCharles.Forsyth 		lput(0);
21574a4d8c2SCharles.Forsyth 		lput(textsize+datsize);
21674a4d8c2SCharles.Forsyth 		lput(textsize+datsize);
21774a4d8c2SCharles.Forsyth 		lput(textsize+datsize);
21874a4d8c2SCharles.Forsyth 		lput(0xd0);			/* header size */
21974a4d8c2SCharles.Forsyth 		lput(0x10400);
22074a4d8c2SCharles.Forsyth 		lput(~0);
22174a4d8c2SCharles.Forsyth 		lput(0);
22274a4d8c2SCharles.Forsyth 		lput(0xc);
22374a4d8c2SCharles.Forsyth 		lput(0xc);
22474a4d8c2SCharles.Forsyth 		lput(0xc);
22574a4d8c2SCharles.Forsyth 		lput(0xc0);
22674a4d8c2SCharles.Forsyth 		lput(0x01010400);
22774a4d8c2SCharles.Forsyth 		lput(~0);
22874a4d8c2SCharles.Forsyth 		lput(0);
22974a4d8c2SCharles.Forsyth 		lput(0x38);
23074a4d8c2SCharles.Forsyth 		lput(0x38);
23174a4d8c2SCharles.Forsyth 		lput(0x38);
23274a4d8c2SCharles.Forsyth 		lput(0x80);
23374a4d8c2SCharles.Forsyth 		lput(0x04040400);
23474a4d8c2SCharles.Forsyth 		lput(0);
23574a4d8c2SCharles.Forsyth 		lput(1);
23674a4d8c2SCharles.Forsyth 		lput(0);
23774a4d8c2SCharles.Forsyth 		lput(~0);
23874a4d8c2SCharles.Forsyth 		lput(0);
23974a4d8c2SCharles.Forsyth 		lput(~0);
24074a4d8c2SCharles.Forsyth 		lput(0);
24174a4d8c2SCharles.Forsyth 		lput(0);
24274a4d8c2SCharles.Forsyth 		lput(0);
24374a4d8c2SCharles.Forsyth 		lput(0);
24474a4d8c2SCharles.Forsyth 		lput(0);
24574a4d8c2SCharles.Forsyth 		lput(0);
24674a4d8c2SCharles.Forsyth 		lput(0);
24774a4d8c2SCharles.Forsyth 		lput(0);
24874a4d8c2SCharles.Forsyth 		lput(0);
24974a4d8c2SCharles.Forsyth 		lput(0);
25074a4d8c2SCharles.Forsyth 		lput(0);
25174a4d8c2SCharles.Forsyth 		lput(0x3100);			/* load address */
25274a4d8c2SCharles.Forsyth 		lput(0);
25374a4d8c2SCharles.Forsyth 		lput(0);
25474a4d8c2SCharles.Forsyth 		lput(0);			/* whew! */
25574a4d8c2SCharles.Forsyth 		break;
25674a4d8c2SCharles.Forsyth 	case 2:
25774a4d8c2SCharles.Forsyth 		if(dlm)
25874a4d8c2SCharles.Forsyth 			lput(0x80000000 | (4*21*21+7));		/* magic */
25974a4d8c2SCharles.Forsyth 		else
26074a4d8c2SCharles.Forsyth 			lput(4*21*21+7);	/* magic */
26174a4d8c2SCharles.Forsyth 		lput(textsize);			/* sizes */
26274a4d8c2SCharles.Forsyth 		lput(datsize);
26374a4d8c2SCharles.Forsyth 		lput(bsssize);
26474a4d8c2SCharles.Forsyth 		lput(symsize);			/* nsyms */
26574a4d8c2SCharles.Forsyth 		lput(entryvalue());		/* va of entry */
26674a4d8c2SCharles.Forsyth 		lput(0L);
26774a4d8c2SCharles.Forsyth 		lput(lcsize);
26874a4d8c2SCharles.Forsyth 		break;
26974a4d8c2SCharles.Forsyth 	case 3:
27074a4d8c2SCharles.Forsyth 		break;
27174a4d8c2SCharles.Forsyth 	case 4:
27274a4d8c2SCharles.Forsyth 		lput((0x1DFL<<16)|3L);		/* magic and sections */
27374a4d8c2SCharles.Forsyth 		lput(time(0));			/* time and date */
27474a4d8c2SCharles.Forsyth 		lput(rnd(HEADR+textsize, 4096)+datsize);
27574a4d8c2SCharles.Forsyth 		lput(symsize);			/* nsyms */
27674a4d8c2SCharles.Forsyth 		lput((0x48L<<16)|15L);		/* size of optional hdr and flags */
27774a4d8c2SCharles.Forsyth 
27874a4d8c2SCharles.Forsyth 		lput((0413<<16)|01L);		/* magic and version */
27974a4d8c2SCharles.Forsyth 		lput(textsize);			/* sizes */
28074a4d8c2SCharles.Forsyth 		lput(datsize);
28174a4d8c2SCharles.Forsyth 		lput(bsssize);
28274a4d8c2SCharles.Forsyth 		lput(entryvalue());		/* va of entry */
28374a4d8c2SCharles.Forsyth 		lput(INITTEXT);			/* va of base of text */
28474a4d8c2SCharles.Forsyth 		lput(INITDAT);			/* va of base of data */
28574a4d8c2SCharles.Forsyth 		lput(INITDAT);			/* address of TOC */
28674a4d8c2SCharles.Forsyth 		lput((1L<<16)|1);		/* sn(entry) | sn(text) */
28774a4d8c2SCharles.Forsyth 		lput((2L<<16)|1);		/* sn(data) | sn(toc) */
28874a4d8c2SCharles.Forsyth 		lput((0L<<16)|3);		/* sn(loader) | sn(bss) */
28974a4d8c2SCharles.Forsyth 		lput((3L<<16)|3);		/* maxalign(text) | maxalign(data) */
29074a4d8c2SCharles.Forsyth 		lput(('1'<<24)|('L'<<16)|0);	/* type field, and reserved */
29174a4d8c2SCharles.Forsyth 		lput(0);			/* max stack allowed */
29274a4d8c2SCharles.Forsyth 		lput(0);			/* max data allowed */
29374a4d8c2SCharles.Forsyth 		lput(0); lput(0); lput(0);	/* reserved */
29474a4d8c2SCharles.Forsyth 
29574a4d8c2SCharles.Forsyth 		strnput(".text", 8);		/* text segment */
29674a4d8c2SCharles.Forsyth 		lput(INITTEXT);			/* address */
29774a4d8c2SCharles.Forsyth 		lput(INITTEXT);
29874a4d8c2SCharles.Forsyth 		lput(textsize);
29974a4d8c2SCharles.Forsyth 		lput(HEADR);
30074a4d8c2SCharles.Forsyth 		lput(0L);
30174a4d8c2SCharles.Forsyth 		lput(HEADR+textsize+datsize+symsize);
30274a4d8c2SCharles.Forsyth 		lput(lcsize);			/* line number size */
30374a4d8c2SCharles.Forsyth 		lput(0x20L);			/* flags */
30474a4d8c2SCharles.Forsyth 
30574a4d8c2SCharles.Forsyth 		strnput(".data", 8);		/* data segment */
30674a4d8c2SCharles.Forsyth 		lput(INITDAT);			/* address */
30774a4d8c2SCharles.Forsyth 		lput(INITDAT);
30874a4d8c2SCharles.Forsyth 		lput(datsize);
30974a4d8c2SCharles.Forsyth 		lput(rnd(HEADR+textsize, 4096));/* sizes */
31074a4d8c2SCharles.Forsyth 		lput(0L);
31174a4d8c2SCharles.Forsyth 		lput(0L);
31274a4d8c2SCharles.Forsyth 		lput(0L);
31374a4d8c2SCharles.Forsyth 		lput(0x40L);			/* flags */
31474a4d8c2SCharles.Forsyth 
31574a4d8c2SCharles.Forsyth 		strnput(".bss", 8);		/* bss segment */
31674a4d8c2SCharles.Forsyth 		lput(INITDAT+datsize);		/* address */
31774a4d8c2SCharles.Forsyth 		lput(INITDAT+datsize);
31874a4d8c2SCharles.Forsyth 		lput(bsssize);
31974a4d8c2SCharles.Forsyth 		lput(0L);
32074a4d8c2SCharles.Forsyth 		lput(0L);
32174a4d8c2SCharles.Forsyth 		lput(0L);
32274a4d8c2SCharles.Forsyth 		lput(0L);
32374a4d8c2SCharles.Forsyth 		lput(0x80L);			/* flags */
32474a4d8c2SCharles.Forsyth 		break;
32574a4d8c2SCharles.Forsyth 	case 5:
326647adfbcSforsyth 		/*
327*45a20ab7Sforsyth 		 * intended for blue/gene
328647adfbcSforsyth 		 */
329*45a20ab7Sforsyth 		elf32(POWER, ELFDATA2MSB, 0, nil);
33074a4d8c2SCharles.Forsyth 		break;
331647adfbcSforsyth 	case 6:
332647adfbcSforsyth 		/*
333*45a20ab7Sforsyth 		 * intended for virtex 4 boot
334647adfbcSforsyth 		 */
335*45a20ab7Sforsyth 		debug['S'] = 1;			/* symbol table */
336*45a20ab7Sforsyth 		elf32(POWER, ELFDATA2MSB, 1, elf32jmp);
337647adfbcSforsyth 		break;
33874a4d8c2SCharles.Forsyth 	}
33974a4d8c2SCharles.Forsyth 	cflush();
34074a4d8c2SCharles.Forsyth }
34174a4d8c2SCharles.Forsyth 
34274a4d8c2SCharles.Forsyth void
strnput(char * s,int n)34374a4d8c2SCharles.Forsyth strnput(char *s, int n)
34474a4d8c2SCharles.Forsyth {
34574a4d8c2SCharles.Forsyth 	for(; *s; s++){
34674a4d8c2SCharles.Forsyth 		CPUT(*s);
34774a4d8c2SCharles.Forsyth 		n--;
34874a4d8c2SCharles.Forsyth 	}
34974a4d8c2SCharles.Forsyth 	for(; n > 0; n--)
35074a4d8c2SCharles.Forsyth 		CPUT(0);
35174a4d8c2SCharles.Forsyth }
35274a4d8c2SCharles.Forsyth 
35374a4d8c2SCharles.Forsyth void
cput(long l)35474a4d8c2SCharles.Forsyth cput(long l)
35574a4d8c2SCharles.Forsyth {
35674a4d8c2SCharles.Forsyth 	CPUT(l);
35774a4d8c2SCharles.Forsyth }
35874a4d8c2SCharles.Forsyth 
35974a4d8c2SCharles.Forsyth void
wput(long l)36074a4d8c2SCharles.Forsyth wput(long l)
36174a4d8c2SCharles.Forsyth {
36274a4d8c2SCharles.Forsyth 	cbp[0] = l>>8;
36374a4d8c2SCharles.Forsyth 	cbp[1] = l;
36474a4d8c2SCharles.Forsyth 	cbp += 2;
36574a4d8c2SCharles.Forsyth 	cbc -= 2;
36674a4d8c2SCharles.Forsyth 	if(cbc <= 0)
36774a4d8c2SCharles.Forsyth 		cflush();
36874a4d8c2SCharles.Forsyth }
36974a4d8c2SCharles.Forsyth 
37074a4d8c2SCharles.Forsyth void
wputl(long l)371*45a20ab7Sforsyth wputl(long l)
372*45a20ab7Sforsyth {
373*45a20ab7Sforsyth 	cbp[0] = l;
374*45a20ab7Sforsyth 	cbp[1] = l>>8;
375*45a20ab7Sforsyth 	cbp += 2;
376*45a20ab7Sforsyth 	cbc -= 2;
377*45a20ab7Sforsyth 	if(cbc <= 0)
378*45a20ab7Sforsyth 		cflush();
379*45a20ab7Sforsyth }
380*45a20ab7Sforsyth 
381*45a20ab7Sforsyth void
lput(long l)38274a4d8c2SCharles.Forsyth lput(long l)
38374a4d8c2SCharles.Forsyth {
38474a4d8c2SCharles.Forsyth 	LPUT(l);
38574a4d8c2SCharles.Forsyth }
38674a4d8c2SCharles.Forsyth 
38774a4d8c2SCharles.Forsyth void
lputl(long c)388*45a20ab7Sforsyth lputl(long c)
389*45a20ab7Sforsyth {
390*45a20ab7Sforsyth 	cbp[0] = (c);
391*45a20ab7Sforsyth 	cbp[1] = (c)>>8;
392*45a20ab7Sforsyth 	cbp[2] = (c)>>16;
393*45a20ab7Sforsyth 	cbp[3] = (c)>>24;
394*45a20ab7Sforsyth 	cbp += 4;
395*45a20ab7Sforsyth 	cbc -= 4;
396*45a20ab7Sforsyth 	if(cbc <= 0)
397*45a20ab7Sforsyth 		cflush();
398*45a20ab7Sforsyth }
399*45a20ab7Sforsyth 
400*45a20ab7Sforsyth void
llput(vlong v)401*45a20ab7Sforsyth llput(vlong v)
402*45a20ab7Sforsyth {
403*45a20ab7Sforsyth 	lput(v>>32);
404*45a20ab7Sforsyth 	lput(v);
405*45a20ab7Sforsyth }
406*45a20ab7Sforsyth 
407*45a20ab7Sforsyth void
llputl(vlong v)408*45a20ab7Sforsyth llputl(vlong v)
409*45a20ab7Sforsyth {
410*45a20ab7Sforsyth 	lputl(v);
411*45a20ab7Sforsyth 	lputl(v>>32);
412*45a20ab7Sforsyth }
413*45a20ab7Sforsyth 
414*45a20ab7Sforsyth void
cflush(void)41574a4d8c2SCharles.Forsyth cflush(void)
41674a4d8c2SCharles.Forsyth {
41774a4d8c2SCharles.Forsyth 	int n;
41874a4d8c2SCharles.Forsyth 
41974a4d8c2SCharles.Forsyth 	n = sizeof(buf.cbuf) - cbc;
42074a4d8c2SCharles.Forsyth 	if(n)
42174a4d8c2SCharles.Forsyth 		write(cout, buf.cbuf, n);
42274a4d8c2SCharles.Forsyth 	cbp = buf.cbuf;
42374a4d8c2SCharles.Forsyth 	cbc = sizeof(buf.cbuf);
42474a4d8c2SCharles.Forsyth }
42574a4d8c2SCharles.Forsyth 
42674a4d8c2SCharles.Forsyth void
asmsym(void)42774a4d8c2SCharles.Forsyth asmsym(void)
42874a4d8c2SCharles.Forsyth {
42974a4d8c2SCharles.Forsyth 	Prog *p;
43074a4d8c2SCharles.Forsyth 	Auto *a;
43174a4d8c2SCharles.Forsyth 	Sym *s;
43274a4d8c2SCharles.Forsyth 	int h;
43374a4d8c2SCharles.Forsyth 
43474a4d8c2SCharles.Forsyth 	s = lookup("etext", 0);
43574a4d8c2SCharles.Forsyth 	if(s->type == STEXT)
43674a4d8c2SCharles.Forsyth 		putsymb(s->name, 'T', s->value, s->version);
43774a4d8c2SCharles.Forsyth 
43874a4d8c2SCharles.Forsyth 	for(h=0; h<NHASH; h++)
43974a4d8c2SCharles.Forsyth 		for(s=hash[h]; s!=S; s=s->link)
44074a4d8c2SCharles.Forsyth 			switch(s->type) {
44174a4d8c2SCharles.Forsyth 			case SCONST:
44274a4d8c2SCharles.Forsyth 				putsymb(s->name, 'D', s->value, s->version);
44374a4d8c2SCharles.Forsyth 				continue;
44474a4d8c2SCharles.Forsyth 
44574a4d8c2SCharles.Forsyth 			case SDATA:
44674a4d8c2SCharles.Forsyth 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
44774a4d8c2SCharles.Forsyth 				continue;
44874a4d8c2SCharles.Forsyth 
44974a4d8c2SCharles.Forsyth 			case SBSS:
45074a4d8c2SCharles.Forsyth 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
45174a4d8c2SCharles.Forsyth 				continue;
45274a4d8c2SCharles.Forsyth 
45374a4d8c2SCharles.Forsyth 			case SFILE:
45474a4d8c2SCharles.Forsyth 				putsymb(s->name, 'f', s->value, s->version);
45574a4d8c2SCharles.Forsyth 				continue;
45674a4d8c2SCharles.Forsyth 			}
45774a4d8c2SCharles.Forsyth 
45874a4d8c2SCharles.Forsyth 	for(p=textp; p!=P; p=p->cond) {
45974a4d8c2SCharles.Forsyth 		s = p->from.sym;
46074a4d8c2SCharles.Forsyth 		if(s->type != STEXT && s->type != SLEAF)
46174a4d8c2SCharles.Forsyth 			continue;
46274a4d8c2SCharles.Forsyth 
46374a4d8c2SCharles.Forsyth 		/* filenames first */
46474a4d8c2SCharles.Forsyth 		for(a=p->to.autom; a; a=a->link)
46574a4d8c2SCharles.Forsyth 			if(a->type == D_FILE)
46674a4d8c2SCharles.Forsyth 				putsymb(a->sym->name, 'z', a->aoffset, 0);
46774a4d8c2SCharles.Forsyth 			else
46874a4d8c2SCharles.Forsyth 			if(a->type == D_FILE1)
46974a4d8c2SCharles.Forsyth 				putsymb(a->sym->name, 'Z', a->aoffset, 0);
47074a4d8c2SCharles.Forsyth 
47174a4d8c2SCharles.Forsyth 		if(s->type == STEXT)
47274a4d8c2SCharles.Forsyth 			putsymb(s->name, 'T', s->value, s->version);
47374a4d8c2SCharles.Forsyth 		else
47474a4d8c2SCharles.Forsyth 			putsymb(s->name, 'L', s->value, s->version);
47574a4d8c2SCharles.Forsyth 
47674a4d8c2SCharles.Forsyth 		/* frame, auto and param after */
47774a4d8c2SCharles.Forsyth 		putsymb(".frame", 'm', p->to.offset+4, 0);
47874a4d8c2SCharles.Forsyth 		for(a=p->to.autom; a; a=a->link)
47974a4d8c2SCharles.Forsyth 			if(a->type == D_AUTO)
48074a4d8c2SCharles.Forsyth 				putsymb(a->sym->name, 'a', -a->aoffset, 0);
48174a4d8c2SCharles.Forsyth 			else
48274a4d8c2SCharles.Forsyth 			if(a->type == D_PARAM)
48374a4d8c2SCharles.Forsyth 				putsymb(a->sym->name, 'p', a->aoffset, 0);
48474a4d8c2SCharles.Forsyth 	}
48574a4d8c2SCharles.Forsyth 	if(debug['v'] || debug['n'])
48674a4d8c2SCharles.Forsyth 		Bprint(&bso, "symsize = %lud\n", symsize);
48774a4d8c2SCharles.Forsyth 	Bflush(&bso);
48874a4d8c2SCharles.Forsyth }
48974a4d8c2SCharles.Forsyth 
49074a4d8c2SCharles.Forsyth void
putsymb(char * s,int t,long v,int ver)49174a4d8c2SCharles.Forsyth putsymb(char *s, int t, long v, int ver)
49274a4d8c2SCharles.Forsyth {
49374a4d8c2SCharles.Forsyth 	int i, f;
49474a4d8c2SCharles.Forsyth 
49574a4d8c2SCharles.Forsyth 	if(t == 'f')
49674a4d8c2SCharles.Forsyth 		s++;
49774a4d8c2SCharles.Forsyth 	LPUT(v);
49874a4d8c2SCharles.Forsyth 	if(ver)
49974a4d8c2SCharles.Forsyth 		t += 'a' - 'A';
50074a4d8c2SCharles.Forsyth 	CPUT(t+0x80);			/* 0x80 is variable length */
50174a4d8c2SCharles.Forsyth 
50274a4d8c2SCharles.Forsyth 	if(t == 'Z' || t == 'z') {
50374a4d8c2SCharles.Forsyth 		CPUT(s[0]);
50474a4d8c2SCharles.Forsyth 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
50574a4d8c2SCharles.Forsyth 			CPUT(s[i]);
50674a4d8c2SCharles.Forsyth 			CPUT(s[i+1]);
50774a4d8c2SCharles.Forsyth 		}
50874a4d8c2SCharles.Forsyth 		CPUT(0);
50974a4d8c2SCharles.Forsyth 		CPUT(0);
51074a4d8c2SCharles.Forsyth 		i++;
51174a4d8c2SCharles.Forsyth 	}
51274a4d8c2SCharles.Forsyth 	else {
51374a4d8c2SCharles.Forsyth 		for(i=0; s[i]; i++)
51474a4d8c2SCharles.Forsyth 			CPUT(s[i]);
51574a4d8c2SCharles.Forsyth 		CPUT(0);
51674a4d8c2SCharles.Forsyth 	}
51774a4d8c2SCharles.Forsyth 	symsize += 4 + 1 + i + 1;
51874a4d8c2SCharles.Forsyth 
51974a4d8c2SCharles.Forsyth 	if(debug['n']) {
52074a4d8c2SCharles.Forsyth 		if(t == 'z' || t == 'Z') {
52174a4d8c2SCharles.Forsyth 			Bprint(&bso, "%c %.8lux ", t, v);
52274a4d8c2SCharles.Forsyth 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
52374a4d8c2SCharles.Forsyth 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
52474a4d8c2SCharles.Forsyth 				Bprint(&bso, "/%x", f);
52574a4d8c2SCharles.Forsyth 			}
52674a4d8c2SCharles.Forsyth 			Bprint(&bso, "\n");
52774a4d8c2SCharles.Forsyth 			return;
52874a4d8c2SCharles.Forsyth 		}
52974a4d8c2SCharles.Forsyth 		if(ver)
53074a4d8c2SCharles.Forsyth 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
53174a4d8c2SCharles.Forsyth 		else
53274a4d8c2SCharles.Forsyth 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
53374a4d8c2SCharles.Forsyth 	}
53474a4d8c2SCharles.Forsyth }
53574a4d8c2SCharles.Forsyth 
53674a4d8c2SCharles.Forsyth #define	MINLC	4
53774a4d8c2SCharles.Forsyth void
asmlc(void)53874a4d8c2SCharles.Forsyth asmlc(void)
53974a4d8c2SCharles.Forsyth {
54074a4d8c2SCharles.Forsyth 	long oldpc, oldlc;
54174a4d8c2SCharles.Forsyth 	Prog *p;
54274a4d8c2SCharles.Forsyth 	long v, s;
54374a4d8c2SCharles.Forsyth 
54474a4d8c2SCharles.Forsyth 	oldpc = INITTEXT;
54574a4d8c2SCharles.Forsyth 	oldlc = 0;
54674a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
54774a4d8c2SCharles.Forsyth 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
54874a4d8c2SCharles.Forsyth 			if(p->as == ATEXT)
54974a4d8c2SCharles.Forsyth 				curtext = p;
550*45a20ab7Sforsyth 			if(debug['V'])
55174a4d8c2SCharles.Forsyth 				Bprint(&bso, "%6lux %P\n",
55274a4d8c2SCharles.Forsyth 					p->pc, p);
55374a4d8c2SCharles.Forsyth 			continue;
55474a4d8c2SCharles.Forsyth 		}
555*45a20ab7Sforsyth 		if(debug['V'])
55674a4d8c2SCharles.Forsyth 			Bprint(&bso, "\t\t%6ld", lcsize);
55774a4d8c2SCharles.Forsyth 		v = (p->pc - oldpc) / MINLC;
55874a4d8c2SCharles.Forsyth 		while(v) {
55974a4d8c2SCharles.Forsyth 			s = 127;
56074a4d8c2SCharles.Forsyth 			if(v < 127)
56174a4d8c2SCharles.Forsyth 				s = v;
56274a4d8c2SCharles.Forsyth 			CPUT(s+128);	/* 129-255 +pc */
563*45a20ab7Sforsyth 			if(debug['V'])
56474a4d8c2SCharles.Forsyth 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
56574a4d8c2SCharles.Forsyth 			v -= s;
56674a4d8c2SCharles.Forsyth 			lcsize++;
56774a4d8c2SCharles.Forsyth 		}
56874a4d8c2SCharles.Forsyth 		s = p->line - oldlc;
56974a4d8c2SCharles.Forsyth 		oldlc = p->line;
57074a4d8c2SCharles.Forsyth 		oldpc = p->pc + MINLC;
57174a4d8c2SCharles.Forsyth 		if(s > 64 || s < -64) {
57274a4d8c2SCharles.Forsyth 			CPUT(0);	/* 0 vv +lc */
57374a4d8c2SCharles.Forsyth 			CPUT(s>>24);
57474a4d8c2SCharles.Forsyth 			CPUT(s>>16);
57574a4d8c2SCharles.Forsyth 			CPUT(s>>8);
57674a4d8c2SCharles.Forsyth 			CPUT(s);
577*45a20ab7Sforsyth 			if(debug['V']) {
57874a4d8c2SCharles.Forsyth 				if(s > 0)
57974a4d8c2SCharles.Forsyth 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
58074a4d8c2SCharles.Forsyth 						s, 0, s);
58174a4d8c2SCharles.Forsyth 				else
58274a4d8c2SCharles.Forsyth 					Bprint(&bso, " lc%ld(%d,%ld)\n",
58374a4d8c2SCharles.Forsyth 						s, 0, s);
58474a4d8c2SCharles.Forsyth 				Bprint(&bso, "%6lux %P\n",
58574a4d8c2SCharles.Forsyth 					p->pc, p);
58674a4d8c2SCharles.Forsyth 			}
58774a4d8c2SCharles.Forsyth 			lcsize += 5;
58874a4d8c2SCharles.Forsyth 			continue;
58974a4d8c2SCharles.Forsyth 		}
59074a4d8c2SCharles.Forsyth 		if(s > 0) {
59174a4d8c2SCharles.Forsyth 			CPUT(0+s);	/* 1-64 +lc */
592*45a20ab7Sforsyth 			if(debug['V']) {
59374a4d8c2SCharles.Forsyth 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
59474a4d8c2SCharles.Forsyth 				Bprint(&bso, "%6lux %P\n",
59574a4d8c2SCharles.Forsyth 					p->pc, p);
59674a4d8c2SCharles.Forsyth 			}
59774a4d8c2SCharles.Forsyth 		} else {
59874a4d8c2SCharles.Forsyth 			CPUT(64-s);	/* 65-128 -lc */
599*45a20ab7Sforsyth 			if(debug['V']) {
60074a4d8c2SCharles.Forsyth 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
60174a4d8c2SCharles.Forsyth 				Bprint(&bso, "%6lux %P\n",
60274a4d8c2SCharles.Forsyth 					p->pc, p);
60374a4d8c2SCharles.Forsyth 			}
60474a4d8c2SCharles.Forsyth 		}
60574a4d8c2SCharles.Forsyth 		lcsize++;
60674a4d8c2SCharles.Forsyth 	}
60774a4d8c2SCharles.Forsyth 	while(lcsize & 1) {
60874a4d8c2SCharles.Forsyth 		s = 129;
60974a4d8c2SCharles.Forsyth 		CPUT(s);
61074a4d8c2SCharles.Forsyth 		lcsize++;
61174a4d8c2SCharles.Forsyth 	}
612*45a20ab7Sforsyth 	if(debug['v'] || debug['V'])
61374a4d8c2SCharles.Forsyth 		Bprint(&bso, "lcsize = %ld\n", lcsize);
61474a4d8c2SCharles.Forsyth 	Bflush(&bso);
61574a4d8c2SCharles.Forsyth }
61674a4d8c2SCharles.Forsyth 
61774a4d8c2SCharles.Forsyth void
datblk(long s,long n)61874a4d8c2SCharles.Forsyth datblk(long s, long n)
61974a4d8c2SCharles.Forsyth {
62074a4d8c2SCharles.Forsyth 	Prog *p;
62174a4d8c2SCharles.Forsyth 	char *cast;
62274a4d8c2SCharles.Forsyth 	long l, fl, j, d;
62374a4d8c2SCharles.Forsyth 	int i, c;
62474a4d8c2SCharles.Forsyth 
62574a4d8c2SCharles.Forsyth 	memset(buf.dbuf, 0, n+100);
62674a4d8c2SCharles.Forsyth 	for(p = datap; p != P; p = p->link) {
62774a4d8c2SCharles.Forsyth 		curp = p;
62874a4d8c2SCharles.Forsyth 		l = p->from.sym->value + p->from.offset - s;
62974a4d8c2SCharles.Forsyth 		c = p->reg;
63074a4d8c2SCharles.Forsyth 		i = 0;
63174a4d8c2SCharles.Forsyth 		if(l < 0) {
63274a4d8c2SCharles.Forsyth 			if(l+c <= 0)
63374a4d8c2SCharles.Forsyth 				continue;
63474a4d8c2SCharles.Forsyth 			while(l < 0) {
63574a4d8c2SCharles.Forsyth 				l++;
63674a4d8c2SCharles.Forsyth 				i++;
63774a4d8c2SCharles.Forsyth 			}
63874a4d8c2SCharles.Forsyth 		}
63974a4d8c2SCharles.Forsyth 		if(l >= n)
64074a4d8c2SCharles.Forsyth 			continue;
64174a4d8c2SCharles.Forsyth 		if(p->as != AINIT && p->as != ADYNT) {
64274a4d8c2SCharles.Forsyth 			for(j=l+(c-i)-1; j>=l; j--)
64374a4d8c2SCharles.Forsyth 				if(buf.dbuf[j]) {
64474a4d8c2SCharles.Forsyth 					print("%P\n", p);
64574a4d8c2SCharles.Forsyth 					diag("multiple initialization");
64674a4d8c2SCharles.Forsyth 					break;
64774a4d8c2SCharles.Forsyth 				}
64874a4d8c2SCharles.Forsyth 		}
64974a4d8c2SCharles.Forsyth 		switch(p->to.type) {
65074a4d8c2SCharles.Forsyth 		default:
65174a4d8c2SCharles.Forsyth 			diag("unknown mode in initialization\n%P", p);
65274a4d8c2SCharles.Forsyth 			break;
65374a4d8c2SCharles.Forsyth 
65474a4d8c2SCharles.Forsyth 		case D_FCONST:
65574a4d8c2SCharles.Forsyth 			switch(c) {
65674a4d8c2SCharles.Forsyth 			default:
65774a4d8c2SCharles.Forsyth 			case 4:
65874a4d8c2SCharles.Forsyth 				fl = ieeedtof(&p->to.ieee);
65974a4d8c2SCharles.Forsyth 				cast = (char*)&fl;
66074a4d8c2SCharles.Forsyth 				for(; i<c; i++) {
66174a4d8c2SCharles.Forsyth 					buf.dbuf[l] = cast[fnuxi8[i+4]];
66274a4d8c2SCharles.Forsyth 					l++;
66374a4d8c2SCharles.Forsyth 				}
66474a4d8c2SCharles.Forsyth 				break;
66574a4d8c2SCharles.Forsyth 			case 8:
66674a4d8c2SCharles.Forsyth 				cast = (char*)&p->to.ieee;
66774a4d8c2SCharles.Forsyth 				for(; i<c; i++) {
66874a4d8c2SCharles.Forsyth 					buf.dbuf[l] = cast[fnuxi8[i]];
66974a4d8c2SCharles.Forsyth 					l++;
67074a4d8c2SCharles.Forsyth 				}
67174a4d8c2SCharles.Forsyth 				break;
67274a4d8c2SCharles.Forsyth 			}
67374a4d8c2SCharles.Forsyth 			break;
67474a4d8c2SCharles.Forsyth 
67574a4d8c2SCharles.Forsyth 		case D_SCONST:
67674a4d8c2SCharles.Forsyth 			for(; i<c; i++) {
67774a4d8c2SCharles.Forsyth 				buf.dbuf[l] = p->to.sval[i];
67874a4d8c2SCharles.Forsyth 				l++;
67974a4d8c2SCharles.Forsyth 			}
68074a4d8c2SCharles.Forsyth 			break;
68174a4d8c2SCharles.Forsyth 
68274a4d8c2SCharles.Forsyth 		case D_CONST:
68374a4d8c2SCharles.Forsyth 			d = p->to.offset;
68474a4d8c2SCharles.Forsyth 			if(p->to.sym) {
68574a4d8c2SCharles.Forsyth 				if(p->to.sym->type == SUNDEF){
68674a4d8c2SCharles.Forsyth 					ckoff(p->to.sym, d);
68774a4d8c2SCharles.Forsyth 					d += p->to.sym->value;
68874a4d8c2SCharles.Forsyth 				}
68974a4d8c2SCharles.Forsyth 				if(p->to.sym->type == STEXT ||
69074a4d8c2SCharles.Forsyth 				   p->to.sym->type == SLEAF)
69174a4d8c2SCharles.Forsyth 					d += p->to.sym->value;
69274a4d8c2SCharles.Forsyth 				if(p->to.sym->type == SDATA)
69374a4d8c2SCharles.Forsyth 					d += p->to.sym->value + INITDAT;
69474a4d8c2SCharles.Forsyth 				if(p->to.sym->type == SBSS)
69574a4d8c2SCharles.Forsyth 					d += p->to.sym->value + INITDAT;
69674a4d8c2SCharles.Forsyth 				if(dlm)
69774a4d8c2SCharles.Forsyth 					dynreloc(p->to.sym, l+s+INITDAT, 1, 0, 0);
69874a4d8c2SCharles.Forsyth 			}
69974a4d8c2SCharles.Forsyth 			cast = (char*)&d;
70074a4d8c2SCharles.Forsyth 			switch(c) {
70174a4d8c2SCharles.Forsyth 			default:
70274a4d8c2SCharles.Forsyth 				diag("bad nuxi %d %d\n%P", c, i, curp);
70374a4d8c2SCharles.Forsyth 				break;
70474a4d8c2SCharles.Forsyth 			case 1:
70574a4d8c2SCharles.Forsyth 				for(; i<c; i++) {
70674a4d8c2SCharles.Forsyth 					buf.dbuf[l] = cast[inuxi1[i]];
70774a4d8c2SCharles.Forsyth 					l++;
70874a4d8c2SCharles.Forsyth 				}
70974a4d8c2SCharles.Forsyth 				break;
71074a4d8c2SCharles.Forsyth 			case 2:
71174a4d8c2SCharles.Forsyth 				for(; i<c; i++) {
71274a4d8c2SCharles.Forsyth 					buf.dbuf[l] = cast[inuxi2[i]];
71374a4d8c2SCharles.Forsyth 					l++;
71474a4d8c2SCharles.Forsyth 				}
71574a4d8c2SCharles.Forsyth 				break;
71674a4d8c2SCharles.Forsyth 			case 4:
71774a4d8c2SCharles.Forsyth 				for(; i<c; i++) {
71874a4d8c2SCharles.Forsyth 					buf.dbuf[l] = cast[inuxi4[i]];
71974a4d8c2SCharles.Forsyth 					l++;
72074a4d8c2SCharles.Forsyth 				}
72174a4d8c2SCharles.Forsyth 				break;
72274a4d8c2SCharles.Forsyth 			}
72374a4d8c2SCharles.Forsyth 			break;
72474a4d8c2SCharles.Forsyth 		}
72574a4d8c2SCharles.Forsyth 	}
72674a4d8c2SCharles.Forsyth 	write(cout, buf.dbuf, n);
72774a4d8c2SCharles.Forsyth }
728