xref: /plan9-contrib/sys/src/cmd/9l/asm.c (revision fbadb1c4d4463e58337ffb1ed396c9caee5d1889)
1*fbadb1c4SDavid du Colombier #include	"l.h"
2*fbadb1c4SDavid du Colombier 
3*fbadb1c4SDavid du Colombier #define PADDR(a)	((a) & ~0xfffffffff0000000ull)
4*fbadb1c4SDavid du Colombier 
5*fbadb1c4SDavid du Colombier #define	LPUT(c)\
6*fbadb1c4SDavid du Colombier 	{\
7*fbadb1c4SDavid du Colombier 		cbp[0] = (c)>>24;\
8*fbadb1c4SDavid du Colombier 		cbp[1] = (c)>>16;\
9*fbadb1c4SDavid du Colombier 		cbp[2] = (c)>>8;\
10*fbadb1c4SDavid du Colombier 		cbp[3] = (c);\
11*fbadb1c4SDavid du Colombier 		cbp += 4;\
12*fbadb1c4SDavid du Colombier 		cbc -= 4;\
13*fbadb1c4SDavid du Colombier 		if(cbc <= 0)\
14*fbadb1c4SDavid du Colombier 			cflush();\
15*fbadb1c4SDavid du Colombier 	}
16*fbadb1c4SDavid du Colombier 
17*fbadb1c4SDavid du Colombier #define	CPUT(c)\
18*fbadb1c4SDavid du Colombier 	{\
19*fbadb1c4SDavid du Colombier 		cbp[0] = (c);\
20*fbadb1c4SDavid du Colombier 		cbp++;\
21*fbadb1c4SDavid du Colombier 		cbc--;\
22*fbadb1c4SDavid du Colombier 		if(cbc <= 0)\
23*fbadb1c4SDavid du Colombier 			cflush();\
24*fbadb1c4SDavid du Colombier 	}
25*fbadb1c4SDavid du Colombier 
26*fbadb1c4SDavid du Colombier vlong
entryvalue(void)27*fbadb1c4SDavid du Colombier entryvalue(void)
28*fbadb1c4SDavid du Colombier {
29*fbadb1c4SDavid du Colombier 	char *a;
30*fbadb1c4SDavid du Colombier 	Sym *s;
31*fbadb1c4SDavid du Colombier 
32*fbadb1c4SDavid du Colombier 	a = INITENTRY;
33*fbadb1c4SDavid du Colombier 	if(*a >= '0' && *a <= '9')
34*fbadb1c4SDavid du Colombier 		return atolwhex(a);
35*fbadb1c4SDavid du Colombier 	s = lookup(a, 0);
36*fbadb1c4SDavid du Colombier 	if(s->type == 0)
37*fbadb1c4SDavid du Colombier 		return INITTEXT;
38*fbadb1c4SDavid du Colombier 	if(dlm && s->type == SDATA)
39*fbadb1c4SDavid du Colombier 		return s->value+INITDAT;
40*fbadb1c4SDavid du Colombier 	if(s->type != STEXT && s->type != SLEAF)
41*fbadb1c4SDavid du Colombier 		diag("entry not text: %s", s->name);
42*fbadb1c4SDavid du Colombier 	return s->value;
43*fbadb1c4SDavid du Colombier }
44*fbadb1c4SDavid du Colombier 
45*fbadb1c4SDavid du Colombier void
asmb(void)46*fbadb1c4SDavid du Colombier asmb(void)
47*fbadb1c4SDavid du Colombier {
48*fbadb1c4SDavid du Colombier 	Prog *p;
49*fbadb1c4SDavid du Colombier 	long t, magic;
50*fbadb1c4SDavid du Colombier 	Optab *o;
51*fbadb1c4SDavid du Colombier 	vlong vl;
52*fbadb1c4SDavid du Colombier 
53*fbadb1c4SDavid du Colombier 	if(debug['v'])
54*fbadb1c4SDavid du Colombier 		Bprint(&bso, "%5.2f asm\n", cputime());
55*fbadb1c4SDavid du Colombier 	Bflush(&bso);
56*fbadb1c4SDavid du Colombier 	seek(cout, HEADR, 0);
57*fbadb1c4SDavid du Colombier 	pc = INITTEXT;
58*fbadb1c4SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
59*fbadb1c4SDavid du Colombier 		if(p->as == ATEXT) {
60*fbadb1c4SDavid du Colombier 			curtext = p;
61*fbadb1c4SDavid du Colombier 			autosize = p->to.offset + 8;
62*fbadb1c4SDavid du Colombier 			if(p->from3.type == D_CONST) {
63*fbadb1c4SDavid du Colombier 				for(; pc < p->pc; pc++)
64*fbadb1c4SDavid du Colombier 					CPUT(0);
65*fbadb1c4SDavid du Colombier 			}
66*fbadb1c4SDavid du Colombier 		}
67*fbadb1c4SDavid du Colombier 		if(p->pc != pc) {
68*fbadb1c4SDavid du Colombier 			diag("phase error %llux sb %llux",
69*fbadb1c4SDavid du Colombier 				p->pc, pc);
70*fbadb1c4SDavid du Colombier 			if(!debug['a'])
71*fbadb1c4SDavid du Colombier 				prasm(curp);
72*fbadb1c4SDavid du Colombier 			pc = p->pc;
73*fbadb1c4SDavid du Colombier 		}
74*fbadb1c4SDavid du Colombier 		curp = p;
75*fbadb1c4SDavid du Colombier 		o = oplook(p);	/* could probably avoid this call */
76*fbadb1c4SDavid du Colombier 		if(asmout(p, o, 0)) {
77*fbadb1c4SDavid du Colombier 			p = p->link;
78*fbadb1c4SDavid du Colombier 			pc += 4;
79*fbadb1c4SDavid du Colombier 		}
80*fbadb1c4SDavid du Colombier 		pc += o->size;
81*fbadb1c4SDavid du Colombier 	}
82*fbadb1c4SDavid du Colombier 	if(debug['a'])
83*fbadb1c4SDavid du Colombier 		Bprint(&bso, "\n");
84*fbadb1c4SDavid du Colombier 	Bflush(&bso);
85*fbadb1c4SDavid du Colombier 	cflush();
86*fbadb1c4SDavid du Colombier 
87*fbadb1c4SDavid du Colombier 	curtext = P;
88*fbadb1c4SDavid du Colombier 	switch(HEADTYPE) {
89*fbadb1c4SDavid du Colombier 	case 0:
90*fbadb1c4SDavid du Colombier 	case 1:
91*fbadb1c4SDavid du Colombier 	case 2:
92*fbadb1c4SDavid du Colombier 	case 5:
93*fbadb1c4SDavid du Colombier 	case 9:
94*fbadb1c4SDavid du Colombier 	case 10:
95*fbadb1c4SDavid du Colombier 		seek(cout, HEADR+textsize, 0);
96*fbadb1c4SDavid du Colombier 		break;
97*fbadb1c4SDavid du Colombier 	case 3:
98*fbadb1c4SDavid du Colombier 		seek(cout, rnd(HEADR+textsize, 4), 0);
99*fbadb1c4SDavid du Colombier 		break;
100*fbadb1c4SDavid du Colombier 	}
101*fbadb1c4SDavid du Colombier 
102*fbadb1c4SDavid du Colombier 	if(dlm){
103*fbadb1c4SDavid du Colombier 		char buf[8];
104*fbadb1c4SDavid du Colombier 
105*fbadb1c4SDavid du Colombier 		write(cout, buf, INITDAT-textsize);
106*fbadb1c4SDavid du Colombier 		textsize = INITDAT;
107*fbadb1c4SDavid du Colombier 	}
108*fbadb1c4SDavid du Colombier 
109*fbadb1c4SDavid du Colombier 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
110*fbadb1c4SDavid du Colombier 		if(datsize-t > sizeof(buf)-100)
111*fbadb1c4SDavid du Colombier 			datblk(t, sizeof(buf)-100);
112*fbadb1c4SDavid du Colombier 		else
113*fbadb1c4SDavid du Colombier 			datblk(t, datsize-t);
114*fbadb1c4SDavid du Colombier 	}
115*fbadb1c4SDavid du Colombier 
116*fbadb1c4SDavid du Colombier 	symsize = 0;
117*fbadb1c4SDavid du Colombier 	lcsize = 0;
118*fbadb1c4SDavid du Colombier 	if(!debug['s']) {
119*fbadb1c4SDavid du Colombier 		if(debug['v'])
120*fbadb1c4SDavid du Colombier 			Bprint(&bso, "%5.2f sym\n", cputime());
121*fbadb1c4SDavid du Colombier 		Bflush(&bso);
122*fbadb1c4SDavid du Colombier 		switch(HEADTYPE) {
123*fbadb1c4SDavid du Colombier 		case 0:
124*fbadb1c4SDavid du Colombier 		case 1:
125*fbadb1c4SDavid du Colombier 		case 2:
126*fbadb1c4SDavid du Colombier 		case 5:
127*fbadb1c4SDavid du Colombier 		case 9:
128*fbadb1c4SDavid du Colombier 		case 10:
129*fbadb1c4SDavid du Colombier 			seek(cout, HEADR+textsize+datsize, 0);
130*fbadb1c4SDavid du Colombier 			break;
131*fbadb1c4SDavid du Colombier 		case 3:
132*fbadb1c4SDavid du Colombier 			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
133*fbadb1c4SDavid du Colombier 			break;
134*fbadb1c4SDavid du Colombier 		}
135*fbadb1c4SDavid du Colombier 		if(!debug['s'])
136*fbadb1c4SDavid du Colombier 			asmsym();
137*fbadb1c4SDavid du Colombier 		if(debug['v'])
138*fbadb1c4SDavid du Colombier 			Bprint(&bso, "%5.2f sp\n", cputime());
139*fbadb1c4SDavid du Colombier 		Bflush(&bso);
140*fbadb1c4SDavid du Colombier 		if(!debug['s'])
141*fbadb1c4SDavid du Colombier 			asmlc();
142*fbadb1c4SDavid du Colombier 		if(dlm)
143*fbadb1c4SDavid du Colombier 			asmdyn();
144*fbadb1c4SDavid du Colombier 		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */
145*fbadb1c4SDavid du Colombier 			if((symsize+lcsize) & 1)
146*fbadb1c4SDavid du Colombier 				CPUT(0);
147*fbadb1c4SDavid du Colombier 		cflush();
148*fbadb1c4SDavid du Colombier 	}
149*fbadb1c4SDavid du Colombier 	else if(dlm){
150*fbadb1c4SDavid du Colombier 		asmdyn();
151*fbadb1c4SDavid du Colombier 		cflush();
152*fbadb1c4SDavid du Colombier 	}
153*fbadb1c4SDavid du Colombier 
154*fbadb1c4SDavid du Colombier 	seek(cout, 0L, 0);
155*fbadb1c4SDavid du Colombier 	switch(HEADTYPE) {
156*fbadb1c4SDavid du Colombier 	case 0:
157*fbadb1c4SDavid du Colombier 		lput(0x1030107);		/* magic and sections */
158*fbadb1c4SDavid du Colombier 		lput(textsize);			/* sizes */
159*fbadb1c4SDavid du Colombier 		lput(datsize);
160*fbadb1c4SDavid du Colombier 		lput(bsssize);
161*fbadb1c4SDavid du Colombier 		lput(symsize);			/* nsyms */
162*fbadb1c4SDavid du Colombier 		lput(entryvalue());		/* va of entry */
163*fbadb1c4SDavid du Colombier 		lput(0L);
164*fbadb1c4SDavid du Colombier 		lput(lcsize);
165*fbadb1c4SDavid du Colombier 		break;
166*fbadb1c4SDavid du Colombier 	case 1:
167*fbadb1c4SDavid du Colombier 		if(dlm)
168*fbadb1c4SDavid du Colombier 			lput(0x80000000 | (4*21*21+7));		/* q.out magic */
169*fbadb1c4SDavid du Colombier 		else
170*fbadb1c4SDavid du Colombier 			lput(4*21*21+7);	/* q.out magic */
171*fbadb1c4SDavid du Colombier 		lput(textsize);			/* sizes */
172*fbadb1c4SDavid du Colombier 		lput(datsize);
173*fbadb1c4SDavid du Colombier 		lput(bsssize);
174*fbadb1c4SDavid du Colombier 		lput(symsize);			/* nsyms */
175*fbadb1c4SDavid du Colombier 		lput(entryvalue());		/* va of entry */
176*fbadb1c4SDavid du Colombier 		lput(0L);
177*fbadb1c4SDavid du Colombier 		lput(lcsize);
178*fbadb1c4SDavid du Colombier 		break;
179*fbadb1c4SDavid du Colombier 	case 2:	/* plan9 */
180*fbadb1c4SDavid du Colombier 		magic = 4*27*27+7;
181*fbadb1c4SDavid du Colombier 		magic |= 0x00008000;		/* fat header */
182*fbadb1c4SDavid du Colombier 		if(dlm)
183*fbadb1c4SDavid du Colombier 			magic |= 0x80000000;	/* dlm */
184*fbadb1c4SDavid du Colombier 		lput(magic);
185*fbadb1c4SDavid du Colombier 		lput(textsize);			/* sizes */
186*fbadb1c4SDavid du Colombier 		lput(datsize);
187*fbadb1c4SDavid du Colombier 		lput(bsssize);
188*fbadb1c4SDavid du Colombier 		lput(symsize);			/* nsyms */
189*fbadb1c4SDavid du Colombier 		vl = entryvalue();
190*fbadb1c4SDavid du Colombier 		lput(PADDR(vl));		/* va of entry (real mode on boot) */
191*fbadb1c4SDavid du Colombier 		lput(0L);
192*fbadb1c4SDavid du Colombier 		lput(lcsize);
193*fbadb1c4SDavid du Colombier 		llput(vl);			/* va of entry */
194*fbadb1c4SDavid du Colombier 		break;
195*fbadb1c4SDavid du Colombier 	case 3:
196*fbadb1c4SDavid du Colombier 		break;
197*fbadb1c4SDavid du Colombier 	case 5:
198*fbadb1c4SDavid du Colombier 		elf32(POWER, ELFDATA2MSB, 0, nil);
199*fbadb1c4SDavid du Colombier 		break;
200*fbadb1c4SDavid du Colombier 	case 9:					/* ELF64 Header */
201*fbadb1c4SDavid du Colombier 	case 10:				/* A2 weirdness */
202*fbadb1c4SDavid du Colombier 		elf64(POWER64, ELFDATA2MSB, 0, nil);
203*fbadb1c4SDavid du Colombier 		break;
204*fbadb1c4SDavid du Colombier 	}
205*fbadb1c4SDavid du Colombier 	cflush();
206*fbadb1c4SDavid du Colombier }
207*fbadb1c4SDavid du Colombier 
208*fbadb1c4SDavid du Colombier void
strnput(char * s,int n)209*fbadb1c4SDavid du Colombier strnput(char *s, int n)
210*fbadb1c4SDavid du Colombier {
211*fbadb1c4SDavid du Colombier 	for(; *s; s++){
212*fbadb1c4SDavid du Colombier 		CPUT(*s);
213*fbadb1c4SDavid du Colombier 		n--;
214*fbadb1c4SDavid du Colombier 	}
215*fbadb1c4SDavid du Colombier 	for(; n > 0; n--)
216*fbadb1c4SDavid du Colombier 		CPUT(0);
217*fbadb1c4SDavid du Colombier }
218*fbadb1c4SDavid du Colombier 
219*fbadb1c4SDavid du Colombier void
cput(long l)220*fbadb1c4SDavid du Colombier cput(long l)
221*fbadb1c4SDavid du Colombier {
222*fbadb1c4SDavid du Colombier 	CPUT(l);
223*fbadb1c4SDavid du Colombier }
224*fbadb1c4SDavid du Colombier 
225*fbadb1c4SDavid du Colombier void
wput(long l)226*fbadb1c4SDavid du Colombier wput(long l)
227*fbadb1c4SDavid du Colombier {
228*fbadb1c4SDavid du Colombier 
229*fbadb1c4SDavid du Colombier 	cbp[0] = l>>8;
230*fbadb1c4SDavid du Colombier 	cbp[1] = l;
231*fbadb1c4SDavid du Colombier 	cbp += 2;
232*fbadb1c4SDavid du Colombier 	cbc -= 2;
233*fbadb1c4SDavid du Colombier 	if(cbc <= 0)
234*fbadb1c4SDavid du Colombier 		cflush();
235*fbadb1c4SDavid du Colombier }
236*fbadb1c4SDavid du Colombier 
237*fbadb1c4SDavid du Colombier void
wputl(long l)238*fbadb1c4SDavid du Colombier wputl(long l)
239*fbadb1c4SDavid du Colombier {
240*fbadb1c4SDavid du Colombier 
241*fbadb1c4SDavid du Colombier 	cbp[0] = l;
242*fbadb1c4SDavid du Colombier 	cbp[1] = l>>8;
243*fbadb1c4SDavid du Colombier 	cbp += 2;
244*fbadb1c4SDavid du Colombier 	cbc -= 2;
245*fbadb1c4SDavid du Colombier 	if(cbc <= 0)
246*fbadb1c4SDavid du Colombier 		cflush();
247*fbadb1c4SDavid du Colombier }
248*fbadb1c4SDavid du Colombier 
249*fbadb1c4SDavid du Colombier void
lput(long l)250*fbadb1c4SDavid du Colombier lput(long l)
251*fbadb1c4SDavid du Colombier {
252*fbadb1c4SDavid du Colombier 
253*fbadb1c4SDavid du Colombier 	cbp[0] = l>>24;
254*fbadb1c4SDavid du Colombier 	cbp[1] = l>>16;
255*fbadb1c4SDavid du Colombier 	cbp[2] = l>>8;
256*fbadb1c4SDavid du Colombier 	cbp[3] = l;
257*fbadb1c4SDavid du Colombier 	cbp += 4;
258*fbadb1c4SDavid du Colombier 	cbc -= 4;
259*fbadb1c4SDavid du Colombier 	if(cbc <= 0)
260*fbadb1c4SDavid du Colombier 		cflush();
261*fbadb1c4SDavid du Colombier }
262*fbadb1c4SDavid du Colombier 
263*fbadb1c4SDavid du Colombier void
lputl(long l)264*fbadb1c4SDavid du Colombier lputl(long l)
265*fbadb1c4SDavid du Colombier {
266*fbadb1c4SDavid du Colombier 
267*fbadb1c4SDavid du Colombier 	cbp[3] = l>>24;
268*fbadb1c4SDavid du Colombier 	cbp[2] = l>>16;
269*fbadb1c4SDavid du Colombier 	cbp[1] = l>>8;
270*fbadb1c4SDavid du Colombier 	cbp[0] = l;
271*fbadb1c4SDavid du Colombier 	cbp += 4;
272*fbadb1c4SDavid du Colombier 	cbc -= 4;
273*fbadb1c4SDavid du Colombier 	if(cbc <= 0)
274*fbadb1c4SDavid du Colombier 		cflush();
275*fbadb1c4SDavid du Colombier }
276*fbadb1c4SDavid du Colombier 
277*fbadb1c4SDavid du Colombier void
llput(vlong v)278*fbadb1c4SDavid du Colombier llput(vlong v)
279*fbadb1c4SDavid du Colombier {
280*fbadb1c4SDavid du Colombier 	lput(v>>32);
281*fbadb1c4SDavid du Colombier 	lput(v);
282*fbadb1c4SDavid du Colombier }
283*fbadb1c4SDavid du Colombier 
284*fbadb1c4SDavid du Colombier void
llputl(vlong v)285*fbadb1c4SDavid du Colombier llputl(vlong v)
286*fbadb1c4SDavid du Colombier {
287*fbadb1c4SDavid du Colombier 	lputl(v);
288*fbadb1c4SDavid du Colombier 	lputl(v>>32);
289*fbadb1c4SDavid du Colombier }
290*fbadb1c4SDavid du Colombier 
291*fbadb1c4SDavid du Colombier void
cflush(void)292*fbadb1c4SDavid du Colombier cflush(void)
293*fbadb1c4SDavid du Colombier {
294*fbadb1c4SDavid du Colombier 	int n;
295*fbadb1c4SDavid du Colombier 
296*fbadb1c4SDavid du Colombier 	n = sizeof(buf.cbuf) - cbc;
297*fbadb1c4SDavid du Colombier 	if(n)
298*fbadb1c4SDavid du Colombier 		write(cout, buf.cbuf, n);
299*fbadb1c4SDavid du Colombier 	cbp = buf.cbuf;
300*fbadb1c4SDavid du Colombier 	cbc = sizeof(buf.cbuf);
301*fbadb1c4SDavid du Colombier }
302*fbadb1c4SDavid du Colombier 
303*fbadb1c4SDavid du Colombier void
asmsym(void)304*fbadb1c4SDavid du Colombier asmsym(void)
305*fbadb1c4SDavid du Colombier {
306*fbadb1c4SDavid du Colombier 	Prog *p;
307*fbadb1c4SDavid du Colombier 	Auto *a;
308*fbadb1c4SDavid du Colombier 	Sym *s;
309*fbadb1c4SDavid du Colombier 	int h;
310*fbadb1c4SDavid du Colombier 
311*fbadb1c4SDavid du Colombier 	s = lookup("etext", 0);
312*fbadb1c4SDavid du Colombier 	if(s->type == STEXT)
313*fbadb1c4SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
314*fbadb1c4SDavid du Colombier 
315*fbadb1c4SDavid du Colombier 	for(h=0; h<NHASH; h++)
316*fbadb1c4SDavid du Colombier 		for(s=hash[h]; s!=S; s=s->link)
317*fbadb1c4SDavid du Colombier 			switch(s->type) {
318*fbadb1c4SDavid du Colombier 			case SCONST:
319*fbadb1c4SDavid du Colombier 				putsymb(s->name, 'D', s->value, s->version);
320*fbadb1c4SDavid du Colombier 				continue;
321*fbadb1c4SDavid du Colombier 
322*fbadb1c4SDavid du Colombier 			case SDATA:
323*fbadb1c4SDavid du Colombier 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
324*fbadb1c4SDavid du Colombier 				continue;
325*fbadb1c4SDavid du Colombier 
326*fbadb1c4SDavid du Colombier 			case SBSS:
327*fbadb1c4SDavid du Colombier 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
328*fbadb1c4SDavid du Colombier 				continue;
329*fbadb1c4SDavid du Colombier 
330*fbadb1c4SDavid du Colombier 			case SFILE:
331*fbadb1c4SDavid du Colombier 				putsymb(s->name, 'f', s->value, s->version);
332*fbadb1c4SDavid du Colombier 				continue;
333*fbadb1c4SDavid du Colombier 			}
334*fbadb1c4SDavid du Colombier 
335*fbadb1c4SDavid du Colombier 	for(p=textp; p!=P; p=p->cond) {
336*fbadb1c4SDavid du Colombier 		s = p->from.sym;
337*fbadb1c4SDavid du Colombier 		if(s->type != STEXT && s->type != SLEAF)
338*fbadb1c4SDavid du Colombier 			continue;
339*fbadb1c4SDavid du Colombier 
340*fbadb1c4SDavid du Colombier 		/* filenames first */
341*fbadb1c4SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
342*fbadb1c4SDavid du Colombier 			if(a->type == D_FILE)
343*fbadb1c4SDavid du Colombier 				putsymb(a->sym->name, 'z', a->aoffset, 0);
344*fbadb1c4SDavid du Colombier 			else
345*fbadb1c4SDavid du Colombier 			if(a->type == D_FILE1)
346*fbadb1c4SDavid du Colombier 				putsymb(a->sym->name, 'Z', a->aoffset, 0);
347*fbadb1c4SDavid du Colombier 
348*fbadb1c4SDavid du Colombier 		if(s->type == STEXT)
349*fbadb1c4SDavid du Colombier 			putsymb(s->name, 'T', s->value, s->version);
350*fbadb1c4SDavid du Colombier 		else
351*fbadb1c4SDavid du Colombier 			putsymb(s->name, 'L', s->value, s->version);
352*fbadb1c4SDavid du Colombier 
353*fbadb1c4SDavid du Colombier 		/* frame, auto and param after */
354*fbadb1c4SDavid du Colombier 		putsymb(".frame", 'm', p->to.offset+8, 0);
355*fbadb1c4SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
356*fbadb1c4SDavid du Colombier 			if(a->type == D_AUTO)
357*fbadb1c4SDavid du Colombier 				putsymb(a->sym->name, 'a', -a->aoffset, 0);
358*fbadb1c4SDavid du Colombier 			else
359*fbadb1c4SDavid du Colombier 			if(a->type == D_PARAM)
360*fbadb1c4SDavid du Colombier 				putsymb(a->sym->name, 'p', a->aoffset, 0);
361*fbadb1c4SDavid du Colombier 	}
362*fbadb1c4SDavid du Colombier 	if(debug['v'] || debug['n'])
363*fbadb1c4SDavid du Colombier 		Bprint(&bso, "symsize = %lud\n", symsize);
364*fbadb1c4SDavid du Colombier 	Bflush(&bso);
365*fbadb1c4SDavid du Colombier }
366*fbadb1c4SDavid du Colombier 
367*fbadb1c4SDavid du Colombier void
putsymb(char * s,int t,vlong v,int ver)368*fbadb1c4SDavid du Colombier putsymb(char *s, int t, vlong v, int ver)
369*fbadb1c4SDavid du Colombier {
370*fbadb1c4SDavid du Colombier 	int i, f, l;
371*fbadb1c4SDavid du Colombier 
372*fbadb1c4SDavid du Colombier 	if(t == 'f')
373*fbadb1c4SDavid du Colombier 		s++;
374*fbadb1c4SDavid du Colombier 
375*fbadb1c4SDavid du Colombier 	l = 4;
376*fbadb1c4SDavid du Colombier 	switch(HEADTYPE){
377*fbadb1c4SDavid du Colombier 	default:
378*fbadb1c4SDavid du Colombier 		break;
379*fbadb1c4SDavid du Colombier 	case 2:
380*fbadb1c4SDavid du Colombier 	case 9:
381*fbadb1c4SDavid du Colombier 	case 10:
382*fbadb1c4SDavid du Colombier 		lput(v>>32);
383*fbadb1c4SDavid du Colombier 		l = 8;
384*fbadb1c4SDavid du Colombier 		break;
385*fbadb1c4SDavid du Colombier 	}
386*fbadb1c4SDavid du Colombier 	lput(v);
387*fbadb1c4SDavid du Colombier 	if(ver)
388*fbadb1c4SDavid du Colombier 		t += 'a' - 'A';
389*fbadb1c4SDavid du Colombier 	cput(t+0x80);			/* 0x80 is variable length */
390*fbadb1c4SDavid du Colombier 
391*fbadb1c4SDavid du Colombier 	if(t == 'Z' || t == 'z') {
392*fbadb1c4SDavid du Colombier 		cput(s[0]);
393*fbadb1c4SDavid du Colombier 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
394*fbadb1c4SDavid du Colombier 			cput(s[i]);
395*fbadb1c4SDavid du Colombier 			cput(s[i+1]);
396*fbadb1c4SDavid du Colombier 		}
397*fbadb1c4SDavid du Colombier 		cput(0);
398*fbadb1c4SDavid du Colombier 		cput(0);
399*fbadb1c4SDavid du Colombier 		i++;
400*fbadb1c4SDavid du Colombier 	}
401*fbadb1c4SDavid du Colombier 	else {
402*fbadb1c4SDavid du Colombier 		for(i=0; s[i]; i++)
403*fbadb1c4SDavid du Colombier 			cput(s[i]);
404*fbadb1c4SDavid du Colombier 		cput(0);
405*fbadb1c4SDavid du Colombier 	}
406*fbadb1c4SDavid du Colombier 	symsize += l + 1 + i + 1;
407*fbadb1c4SDavid du Colombier 
408*fbadb1c4SDavid du Colombier 	if(debug['n']) {
409*fbadb1c4SDavid du Colombier 		if(t == 'z' || t == 'Z') {
410*fbadb1c4SDavid du Colombier 			Bprint(&bso, "%c %.8llux ", t, v);
411*fbadb1c4SDavid du Colombier 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
412*fbadb1c4SDavid du Colombier 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
413*fbadb1c4SDavid du Colombier 				Bprint(&bso, "/%x", f);
414*fbadb1c4SDavid du Colombier 			}
415*fbadb1c4SDavid du Colombier 			Bprint(&bso, "\n");
416*fbadb1c4SDavid du Colombier 			return;
417*fbadb1c4SDavid du Colombier 		}
418*fbadb1c4SDavid du Colombier 		if(ver)
419*fbadb1c4SDavid du Colombier 			Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver);
420*fbadb1c4SDavid du Colombier 		else
421*fbadb1c4SDavid du Colombier 			Bprint(&bso, "%c %.8llux %s\n", t, v, s);
422*fbadb1c4SDavid du Colombier 	}
423*fbadb1c4SDavid du Colombier }
424*fbadb1c4SDavid du Colombier 
425*fbadb1c4SDavid du Colombier #define	MINLC	4
426*fbadb1c4SDavid du Colombier void
asmlc(void)427*fbadb1c4SDavid du Colombier asmlc(void)
428*fbadb1c4SDavid du Colombier {
429*fbadb1c4SDavid du Colombier 	vlong oldpc, oldlc;
430*fbadb1c4SDavid du Colombier 	Prog *p;
431*fbadb1c4SDavid du Colombier 	long v, s;
432*fbadb1c4SDavid du Colombier 
433*fbadb1c4SDavid du Colombier 	oldpc = INITTEXT;
434*fbadb1c4SDavid du Colombier 	oldlc = 0;
435*fbadb1c4SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
436*fbadb1c4SDavid du Colombier 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
437*fbadb1c4SDavid du Colombier 			if(p->as == ATEXT)
438*fbadb1c4SDavid du Colombier 				curtext = p;
439*fbadb1c4SDavid du Colombier 			if(debug['V'])
440*fbadb1c4SDavid du Colombier 				Bprint(&bso, "%6llux %P\n",
441*fbadb1c4SDavid du Colombier 					p->pc, p);
442*fbadb1c4SDavid du Colombier 			continue;
443*fbadb1c4SDavid du Colombier 		}
444*fbadb1c4SDavid du Colombier 		if(debug['V'])
445*fbadb1c4SDavid du Colombier 			Bprint(&bso, "\t\t%6ld", lcsize);
446*fbadb1c4SDavid du Colombier 		v = (p->pc - oldpc) / MINLC;
447*fbadb1c4SDavid du Colombier 		while(v) {
448*fbadb1c4SDavid du Colombier 			s = 127;
449*fbadb1c4SDavid du Colombier 			if(v < 127)
450*fbadb1c4SDavid du Colombier 				s = v;
451*fbadb1c4SDavid du Colombier 			CPUT(s+128);	/* 129-255 +pc */
452*fbadb1c4SDavid du Colombier 			if(debug['V'])
453*fbadb1c4SDavid du Colombier 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
454*fbadb1c4SDavid du Colombier 			v -= s;
455*fbadb1c4SDavid du Colombier 			lcsize++;
456*fbadb1c4SDavid du Colombier 		}
457*fbadb1c4SDavid du Colombier 		s = p->line - oldlc;
458*fbadb1c4SDavid du Colombier 		oldlc = p->line;
459*fbadb1c4SDavid du Colombier 		oldpc = p->pc + MINLC;
460*fbadb1c4SDavid du Colombier 		if(s > 64 || s < -64) {
461*fbadb1c4SDavid du Colombier 			CPUT(0);	/* 0 vv +lc */
462*fbadb1c4SDavid du Colombier 			CPUT(s>>24);
463*fbadb1c4SDavid du Colombier 			CPUT(s>>16);
464*fbadb1c4SDavid du Colombier 			CPUT(s>>8);
465*fbadb1c4SDavid du Colombier 			CPUT(s);
466*fbadb1c4SDavid du Colombier 			if(debug['V']) {
467*fbadb1c4SDavid du Colombier 				if(s > 0)
468*fbadb1c4SDavid du Colombier 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
469*fbadb1c4SDavid du Colombier 						s, 0, s);
470*fbadb1c4SDavid du Colombier 				else
471*fbadb1c4SDavid du Colombier 					Bprint(&bso, " lc%ld(%d,%ld)\n",
472*fbadb1c4SDavid du Colombier 						s, 0, s);
473*fbadb1c4SDavid du Colombier 				Bprint(&bso, "%6llux %P\n",
474*fbadb1c4SDavid du Colombier 					p->pc, p);
475*fbadb1c4SDavid du Colombier 			}
476*fbadb1c4SDavid du Colombier 			lcsize += 5;
477*fbadb1c4SDavid du Colombier 			continue;
478*fbadb1c4SDavid du Colombier 		}
479*fbadb1c4SDavid du Colombier 		if(s > 0) {
480*fbadb1c4SDavid du Colombier 			CPUT(0+s);	/* 1-64 +lc */
481*fbadb1c4SDavid du Colombier 			if(debug['V']) {
482*fbadb1c4SDavid du Colombier 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
483*fbadb1c4SDavid du Colombier 				Bprint(&bso, "%6llux %P\n",
484*fbadb1c4SDavid du Colombier 					p->pc, p);
485*fbadb1c4SDavid du Colombier 			}
486*fbadb1c4SDavid du Colombier 		} else {
487*fbadb1c4SDavid du Colombier 			CPUT(64-s);	/* 65-128 -lc */
488*fbadb1c4SDavid du Colombier 			if(debug['V']) {
489*fbadb1c4SDavid du Colombier 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
490*fbadb1c4SDavid du Colombier 				Bprint(&bso, "%6llux %P\n",
491*fbadb1c4SDavid du Colombier 					p->pc, p);
492*fbadb1c4SDavid du Colombier 			}
493*fbadb1c4SDavid du Colombier 		}
494*fbadb1c4SDavid du Colombier 		lcsize++;
495*fbadb1c4SDavid du Colombier 	}
496*fbadb1c4SDavid du Colombier 	while(lcsize & 1) {
497*fbadb1c4SDavid du Colombier 		s = 129;
498*fbadb1c4SDavid du Colombier 		CPUT(s);
499*fbadb1c4SDavid du Colombier 		lcsize++;
500*fbadb1c4SDavid du Colombier 	}
501*fbadb1c4SDavid du Colombier 	if(debug['v'] || debug['V'])
502*fbadb1c4SDavid du Colombier 		Bprint(&bso, "lcsize = %ld\n", lcsize);
503*fbadb1c4SDavid du Colombier 	Bflush(&bso);
504*fbadb1c4SDavid du Colombier }
505*fbadb1c4SDavid du Colombier 
506*fbadb1c4SDavid du Colombier void
datblk(long s,long n)507*fbadb1c4SDavid du Colombier datblk(long s, long n)
508*fbadb1c4SDavid du Colombier {
509*fbadb1c4SDavid du Colombier 	Prog *p;
510*fbadb1c4SDavid du Colombier 	uchar *cast;
511*fbadb1c4SDavid du Colombier 	long l, fl, j;
512*fbadb1c4SDavid du Colombier 	vlong d;
513*fbadb1c4SDavid du Colombier 	int i, c;
514*fbadb1c4SDavid du Colombier 
515*fbadb1c4SDavid du Colombier 	memset(buf.dbuf, 0, n+100);
516*fbadb1c4SDavid du Colombier 	for(p = datap; p != P; p = p->link) {
517*fbadb1c4SDavid du Colombier 		curp = p;
518*fbadb1c4SDavid du Colombier 		l = p->from.sym->value + p->from.offset - s;
519*fbadb1c4SDavid du Colombier 		c = p->reg;
520*fbadb1c4SDavid du Colombier 		i = 0;
521*fbadb1c4SDavid du Colombier 		if(l < 0) {
522*fbadb1c4SDavid du Colombier 			if(l+c <= 0)
523*fbadb1c4SDavid du Colombier 				continue;
524*fbadb1c4SDavid du Colombier 			while(l < 0) {
525*fbadb1c4SDavid du Colombier 				l++;
526*fbadb1c4SDavid du Colombier 				i++;
527*fbadb1c4SDavid du Colombier 			}
528*fbadb1c4SDavid du Colombier 		}
529*fbadb1c4SDavid du Colombier 		if(l >= n)
530*fbadb1c4SDavid du Colombier 			continue;
531*fbadb1c4SDavid du Colombier 		if(p->as != AINIT && p->as != ADYNT) {
532*fbadb1c4SDavid du Colombier 			for(j=l+(c-i)-1; j>=l; j--)
533*fbadb1c4SDavid du Colombier 				if(buf.dbuf[j]) {
534*fbadb1c4SDavid du Colombier 					print("%P\n", p);
535*fbadb1c4SDavid du Colombier 					diag("multiple initialization");
536*fbadb1c4SDavid du Colombier 					break;
537*fbadb1c4SDavid du Colombier 				}
538*fbadb1c4SDavid du Colombier 		}
539*fbadb1c4SDavid du Colombier 		switch(p->to.type) {
540*fbadb1c4SDavid du Colombier 		default:
541*fbadb1c4SDavid du Colombier 			diag("unknown mode in initialization\n%P", p);
542*fbadb1c4SDavid du Colombier 			break;
543*fbadb1c4SDavid du Colombier 
544*fbadb1c4SDavid du Colombier 		case D_FCONST:
545*fbadb1c4SDavid du Colombier 			switch(c) {
546*fbadb1c4SDavid du Colombier 			default:
547*fbadb1c4SDavid du Colombier 			case 4:
548*fbadb1c4SDavid du Colombier 				fl = ieeedtof(&p->to.ieee);
549*fbadb1c4SDavid du Colombier 				cast = (uchar*)&fl;
550*fbadb1c4SDavid du Colombier 				for(; i<c; i++) {
551*fbadb1c4SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i+4]];
552*fbadb1c4SDavid du Colombier 					l++;
553*fbadb1c4SDavid du Colombier 				}
554*fbadb1c4SDavid du Colombier 				break;
555*fbadb1c4SDavid du Colombier 			case 8:
556*fbadb1c4SDavid du Colombier 				cast = (uchar*)&p->to.ieee;
557*fbadb1c4SDavid du Colombier 				for(; i<c; i++) {
558*fbadb1c4SDavid du Colombier 					buf.dbuf[l] = cast[fnuxi8[i]];
559*fbadb1c4SDavid du Colombier 					l++;
560*fbadb1c4SDavid du Colombier 				}
561*fbadb1c4SDavid du Colombier 				break;
562*fbadb1c4SDavid du Colombier 			}
563*fbadb1c4SDavid du Colombier 			break;
564*fbadb1c4SDavid du Colombier 
565*fbadb1c4SDavid du Colombier 		case D_SCONST:
566*fbadb1c4SDavid du Colombier 			for(; i<c; i++) {
567*fbadb1c4SDavid du Colombier 				buf.dbuf[l] = p->to.sval[i];
568*fbadb1c4SDavid du Colombier 				l++;
569*fbadb1c4SDavid du Colombier 			}
570*fbadb1c4SDavid du Colombier 			break;
571*fbadb1c4SDavid du Colombier 
572*fbadb1c4SDavid du Colombier 		case D_DCONST:
573*fbadb1c4SDavid du Colombier 		case D_CONST:
574*fbadb1c4SDavid du Colombier 			d = p->to.offset;
575*fbadb1c4SDavid du Colombier 			if(p->to.sym) {
576*fbadb1c4SDavid du Colombier 				if(p->to.sym->type == SUNDEF){	/* TO DO: simplify */
577*fbadb1c4SDavid du Colombier 					ckoff(p->to.sym, d);
578*fbadb1c4SDavid du Colombier 					d += p->to.sym->value;
579*fbadb1c4SDavid du Colombier 				}
580*fbadb1c4SDavid du Colombier 				if(p->to.sym->type == STEXT ||
581*fbadb1c4SDavid du Colombier 				   p->to.sym->type == SLEAF)
582*fbadb1c4SDavid du Colombier 					d += p->to.sym->value;
583*fbadb1c4SDavid du Colombier 				if(p->to.sym->type == SDATA)
584*fbadb1c4SDavid du Colombier 					d += p->to.sym->value + INITDAT;
585*fbadb1c4SDavid du Colombier 				if(p->to.sym->type == SBSS)
586*fbadb1c4SDavid du Colombier 					d += p->to.sym->value + INITDAT;
587*fbadb1c4SDavid du Colombier 				if(dlm)
588*fbadb1c4SDavid du Colombier 					dynreloc(p->to.sym, l+s+INITDAT, 1, 0, 0);
589*fbadb1c4SDavid du Colombier 			}
590*fbadb1c4SDavid du Colombier 			fl = d;
591*fbadb1c4SDavid du Colombier 			cast = (uchar*)&fl;
592*fbadb1c4SDavid du Colombier 			switch(c) {
593*fbadb1c4SDavid du Colombier 			default:
594*fbadb1c4SDavid du Colombier 				diag("bad nuxi %d %d\n%P", c, i, curp);
595*fbadb1c4SDavid du Colombier 				break;
596*fbadb1c4SDavid du Colombier 			case 1:
597*fbadb1c4SDavid du Colombier 				for(; i<c; i++) {
598*fbadb1c4SDavid du Colombier 					buf.dbuf[l] = cast[inuxi1[i]];
599*fbadb1c4SDavid du Colombier 					l++;
600*fbadb1c4SDavid du Colombier 				}
601*fbadb1c4SDavid du Colombier 				break;
602*fbadb1c4SDavid du Colombier 			case 2:
603*fbadb1c4SDavid du Colombier 				for(; i<c; i++) {
604*fbadb1c4SDavid du Colombier 					buf.dbuf[l] = cast[inuxi2[i]];
605*fbadb1c4SDavid du Colombier 					l++;
606*fbadb1c4SDavid du Colombier 				}
607*fbadb1c4SDavid du Colombier 				break;
608*fbadb1c4SDavid du Colombier 			case 4:
609*fbadb1c4SDavid du Colombier 				for(; i<c; i++) {
610*fbadb1c4SDavid du Colombier 					buf.dbuf[l] = cast[inuxi4[i]];
611*fbadb1c4SDavid du Colombier 					l++;
612*fbadb1c4SDavid du Colombier 				}
613*fbadb1c4SDavid du Colombier 				break;
614*fbadb1c4SDavid du Colombier 			case 8:
615*fbadb1c4SDavid du Colombier 				cast = (uchar*)&d;
616*fbadb1c4SDavid du Colombier 				for(; i<c; i++) {
617*fbadb1c4SDavid du Colombier 					buf.dbuf[l] = cast[inuxi8[i]];
618*fbadb1c4SDavid du Colombier 					l++;
619*fbadb1c4SDavid du Colombier 				}
620*fbadb1c4SDavid du Colombier 				break;
621*fbadb1c4SDavid du Colombier 			}
622*fbadb1c4SDavid du Colombier 			break;
623*fbadb1c4SDavid du Colombier 		}
624*fbadb1c4SDavid du Colombier 	}
625*fbadb1c4SDavid du Colombier 	write(cout, buf.dbuf, n);
626*fbadb1c4SDavid du Colombier }
627