xref: /plan9-contrib/sys/src/cmd/6l/list.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
1e887ea33SDavid du Colombier #include	"l.h"
2e887ea33SDavid du Colombier 
3e887ea33SDavid du Colombier void
listinit(void)4e887ea33SDavid du Colombier listinit(void)
5e887ea33SDavid du Colombier {
6e887ea33SDavid du Colombier 
7e887ea33SDavid du Colombier 	fmtinstall('R', Rconv);
8e887ea33SDavid du Colombier 	fmtinstall('A', Aconv);
9e887ea33SDavid du Colombier 	fmtinstall('D', Dconv);
10e887ea33SDavid du Colombier 	fmtinstall('S', Sconv);
11e887ea33SDavid du Colombier 	fmtinstall('P', Pconv);
12e887ea33SDavid du Colombier }
13e887ea33SDavid du Colombier 
14e887ea33SDavid du Colombier static	Prog	*bigP;
15e887ea33SDavid du Colombier 
16e887ea33SDavid du Colombier int
Pconv(Fmt * fp)17e887ea33SDavid du Colombier Pconv(Fmt *fp)
18e887ea33SDavid du Colombier {
19e887ea33SDavid du Colombier 	char str[STRINGSZ];
20e887ea33SDavid du Colombier 	Prog *p;
21e887ea33SDavid du Colombier 
22e887ea33SDavid du Colombier 	p = va_arg(fp->args, Prog*);
23e887ea33SDavid du Colombier 	bigP = p;
24e887ea33SDavid du Colombier 	switch(p->as) {
25e887ea33SDavid du Colombier 	case ATEXT:
26e887ea33SDavid du Colombier 		if(p->from.scale) {
27*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "(%ld)	%A	%D,%d,%D",
28e887ea33SDavid du Colombier 				p->line, p->as, &p->from, p->from.scale, &p->to);
29e887ea33SDavid du Colombier 			break;
30e887ea33SDavid du Colombier 		}
31e887ea33SDavid du Colombier 	default:
32*40d01547SDavid du Colombier 		if(isxyreg(p->to.type) && p->to.index != D_NONE)
33*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "(%ld)	V%A	%D,%R,%R",
34*40d01547SDavid du Colombier 				p->line, p->as, &p->from, p->to.index, p->to.type);
35*40d01547SDavid du Colombier 		else if(isxyreg(p->from.type) && p->from.index != D_NONE)
36*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "(%ld)	V%A	%R,%R,%D",
37*40d01547SDavid du Colombier 				p->line, p->as, p->from.type, p->from.index, &p->to);
38*40d01547SDavid du Colombier 		else
39*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "(%ld)	%A	%D,%D",
40e887ea33SDavid du Colombier 				p->line, p->as, &p->from, &p->to);
41e887ea33SDavid du Colombier 		break;
42e887ea33SDavid du Colombier 	case ADATA:
43e887ea33SDavid du Colombier 	case AINIT:
44e887ea33SDavid du Colombier 	case ADYNT:
45*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "(%ld)	%A	%D/%d,%D",
46e887ea33SDavid du Colombier 			p->line, p->as, &p->from, p->from.scale, &p->to);
47e887ea33SDavid du Colombier 		break;
48e887ea33SDavid du Colombier 	}
49e887ea33SDavid du Colombier 	bigP = P;
50e887ea33SDavid du Colombier 	return fmtstrcpy(fp, str);
51e887ea33SDavid du Colombier }
52e887ea33SDavid du Colombier 
53e887ea33SDavid du Colombier int
Aconv(Fmt * fp)54e887ea33SDavid du Colombier Aconv(Fmt *fp)
55e887ea33SDavid du Colombier {
56e887ea33SDavid du Colombier 	int i;
57e887ea33SDavid du Colombier 
58e887ea33SDavid du Colombier 	i = va_arg(fp->args, int);
59e887ea33SDavid du Colombier 	return fmtstrcpy(fp, anames[i]);
60e887ea33SDavid du Colombier }
61e887ea33SDavid du Colombier 
62e887ea33SDavid du Colombier int
Dconv(Fmt * fp)63e887ea33SDavid du Colombier Dconv(Fmt *fp)
64e887ea33SDavid du Colombier {
65*40d01547SDavid du Colombier 	char str[STRINGSZ+40], s[20];
66e887ea33SDavid du Colombier 	Adr *a;
67e887ea33SDavid du Colombier 	int i;
68e887ea33SDavid du Colombier 
69e887ea33SDavid du Colombier 	a = va_arg(fp->args, Adr*);
70e887ea33SDavid du Colombier 	i = a->type;
71*40d01547SDavid du Colombier 	if(i >= D_INDIR && i < D_CONST2) {
72e887ea33SDavid du Colombier 		if(a->offset)
73*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
74e887ea33SDavid du Colombier 		else
75*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "(%R)", i-D_INDIR);
76e887ea33SDavid du Colombier 		goto brk;
77e887ea33SDavid du Colombier 	}
78e887ea33SDavid du Colombier 	switch(i) {
79e887ea33SDavid du Colombier 
80e887ea33SDavid du Colombier 	default:
81e887ea33SDavid du Colombier 		if(a->offset)
82*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
83e887ea33SDavid du Colombier 		else
84*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%R", i);
85e887ea33SDavid du Colombier 		break;
86e887ea33SDavid du Colombier 
87e887ea33SDavid du Colombier 	case D_NONE:
88e887ea33SDavid du Colombier 		str[0] = 0;
89e887ea33SDavid du Colombier 		break;
90e887ea33SDavid du Colombier 
91e887ea33SDavid du Colombier 	case D_BRANCH:
92e887ea33SDavid du Colombier 		if(bigP != P && bigP->pcond != P)
93e887ea33SDavid du Colombier 			if(a->sym != S)
94*40d01547SDavid du Colombier 				snprint(str, sizeof(str), "%llux+%s", bigP->pcond->pc,
95e887ea33SDavid du Colombier 					a->sym->name);
96e887ea33SDavid du Colombier 			else
97*40d01547SDavid du Colombier 				snprint(str, sizeof(str), "%llux", bigP->pcond->pc);
98e887ea33SDavid du Colombier 		else
99*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%lld(PC)", a->offset);
100e887ea33SDavid du Colombier 		break;
101e887ea33SDavid du Colombier 
102e887ea33SDavid du Colombier 	case D_EXTERN:
103*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "%s+%lld(SB)", a->sym->name, a->offset);
104e887ea33SDavid du Colombier 		break;
105e887ea33SDavid du Colombier 
106e887ea33SDavid du Colombier 	case D_STATIC:
107*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "%s<%d>+%lld(SB)", a->sym->name,
108e887ea33SDavid du Colombier 			a->sym->version, a->offset);
109e887ea33SDavid du Colombier 		break;
110e887ea33SDavid du Colombier 
111e887ea33SDavid du Colombier 	case D_AUTO:
112*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "%s+%lld(SP)", a->sym->name, a->offset);
113e887ea33SDavid du Colombier 		break;
114e887ea33SDavid du Colombier 
115e887ea33SDavid du Colombier 	case D_PARAM:
116e887ea33SDavid du Colombier 		if(a->sym)
117*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
118e887ea33SDavid du Colombier 		else
119*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%lld(%s)", a->offset, paramspace);
120e887ea33SDavid du Colombier 		break;
121e887ea33SDavid du Colombier 
122e887ea33SDavid du Colombier 	case D_CONST:
123*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "$%lld", a->offset);
124e887ea33SDavid du Colombier 		break;
125e887ea33SDavid du Colombier 
126e887ea33SDavid du Colombier 	case D_FCONST:
127*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
128e887ea33SDavid du Colombier 		break;
129e887ea33SDavid du Colombier 
130e887ea33SDavid du Colombier 	case D_SCONST:
131*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "$\"%S\"", a->scon);
132e887ea33SDavid du Colombier 		break;
133e887ea33SDavid du Colombier 
134e887ea33SDavid du Colombier 	case D_ADDR:
135e887ea33SDavid du Colombier 		a->type = a->index;
136e887ea33SDavid du Colombier 		a->index = D_NONE;
137*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "$%D", a);
138e887ea33SDavid du Colombier 		a->index = a->type;
139e887ea33SDavid du Colombier 		a->type = D_ADDR;
140e887ea33SDavid du Colombier 		goto conv;
141e887ea33SDavid du Colombier 	}
142e887ea33SDavid du Colombier brk:
143*40d01547SDavid du Colombier 	if(a->index != D_NONE && !isxyreg(a->type)) {
144*40d01547SDavid du Colombier 		snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
145e887ea33SDavid du Colombier 		strcat(str, s);
146e887ea33SDavid du Colombier 	}
147e887ea33SDavid du Colombier conv:
148e887ea33SDavid du Colombier 	return fmtstrcpy(fp, str);
149e887ea33SDavid du Colombier }
150e887ea33SDavid du Colombier 
151e887ea33SDavid du Colombier char*	regstr[] =
152e887ea33SDavid du Colombier {
153e887ea33SDavid du Colombier 	"AL",		/* [D_AL] */
154e887ea33SDavid du Colombier 	"CL",
155e887ea33SDavid du Colombier 	"DL",
156e887ea33SDavid du Colombier 	"BL",
157e887ea33SDavid du Colombier 	"SPB",
158e887ea33SDavid du Colombier 	"BPB",
159e887ea33SDavid du Colombier 	"SIB",
160e887ea33SDavid du Colombier 	"DIB",
161e887ea33SDavid du Colombier 	"R8B",
162e887ea33SDavid du Colombier 	"R9B",
163e887ea33SDavid du Colombier 	"R10B",
164e887ea33SDavid du Colombier 	"R11B",
165e887ea33SDavid du Colombier 	"R12B",
166e887ea33SDavid du Colombier 	"R13B",
167e887ea33SDavid du Colombier 	"R14B",
168e887ea33SDavid du Colombier 	"R15B",
169e887ea33SDavid du Colombier 
170e887ea33SDavid du Colombier 	"AX",		/* [D_AX] */
171e887ea33SDavid du Colombier 	"CX",
172e887ea33SDavid du Colombier 	"DX",
173e887ea33SDavid du Colombier 	"BX",
174e887ea33SDavid du Colombier 	"SP",
175e887ea33SDavid du Colombier 	"BP",
176e887ea33SDavid du Colombier 	"SI",
177e887ea33SDavid du Colombier 	"DI",
178e887ea33SDavid du Colombier 	"R8",
179e887ea33SDavid du Colombier 	"R9",
180e887ea33SDavid du Colombier 	"R10",
181e887ea33SDavid du Colombier 	"R11",
182e887ea33SDavid du Colombier 	"R12",
183e887ea33SDavid du Colombier 	"R13",
184e887ea33SDavid du Colombier 	"R14",
185e887ea33SDavid du Colombier 	"R15",
186e887ea33SDavid du Colombier 
187e887ea33SDavid du Colombier 	"AH",
188e887ea33SDavid du Colombier 	"CH",
189e887ea33SDavid du Colombier 	"DH",
190e887ea33SDavid du Colombier 	"BH",
191e887ea33SDavid du Colombier 
192*40d01547SDavid du Colombier 	"Y0",		/* [D_Y0] */
193*40d01547SDavid du Colombier 	"Y1",
194*40d01547SDavid du Colombier 	"Y2",
195*40d01547SDavid du Colombier 	"Y3",
196*40d01547SDavid du Colombier 	"Y4",
197*40d01547SDavid du Colombier 	"Y5",
198*40d01547SDavid du Colombier 	"Y6",
199*40d01547SDavid du Colombier 	"Y7",
200e887ea33SDavid du Colombier 
201*40d01547SDavid du Colombier 	"Y8",
202*40d01547SDavid du Colombier 	"Y9",
203*40d01547SDavid du Colombier 	"Y10",
204*40d01547SDavid du Colombier 	"Y11",
205*40d01547SDavid du Colombier 	"Y12",
206*40d01547SDavid du Colombier 	"Y13",
207*40d01547SDavid du Colombier 	"Y14",
208*40d01547SDavid du Colombier 	"Y15",
209e887ea33SDavid du Colombier 
210e887ea33SDavid du Colombier 	"X0",
211e887ea33SDavid du Colombier 	"X1",
212e887ea33SDavid du Colombier 	"X2",
213e887ea33SDavid du Colombier 	"X3",
214e887ea33SDavid du Colombier 	"X4",
215e887ea33SDavid du Colombier 	"X5",
216e887ea33SDavid du Colombier 	"X6",
217e887ea33SDavid du Colombier 	"X7",
218e887ea33SDavid du Colombier 	"X8",
219e887ea33SDavid du Colombier 	"X9",
220e887ea33SDavid du Colombier 	"X10",
221e887ea33SDavid du Colombier 	"X11",
222e887ea33SDavid du Colombier 	"X12",
223e887ea33SDavid du Colombier 	"X13",
224e887ea33SDavid du Colombier 	"X14",
225e887ea33SDavid du Colombier 	"X15",
226e887ea33SDavid du Colombier 
227e887ea33SDavid du Colombier 	"CS",		/* [D_CS] */
228e887ea33SDavid du Colombier 	"SS",
229e887ea33SDavid du Colombier 	"DS",
230e887ea33SDavid du Colombier 	"ES",
231e887ea33SDavid du Colombier 	"FS",
232e887ea33SDavid du Colombier 	"GS",
233e887ea33SDavid du Colombier 
234e887ea33SDavid du Colombier 	"GDTR",		/* [D_GDTR] */
235e887ea33SDavid du Colombier 	"IDTR",		/* [D_IDTR] */
236e887ea33SDavid du Colombier 	"LDTR",		/* [D_LDTR] */
237e887ea33SDavid du Colombier 	"MSW",		/* [D_MSW] */
238e887ea33SDavid du Colombier 	"TASK",		/* [D_TASK] */
239e887ea33SDavid du Colombier 
240e887ea33SDavid du Colombier 	"CR0",		/* [D_CR] */
241e887ea33SDavid du Colombier 	"CR1",
242e887ea33SDavid du Colombier 	"CR2",
243e887ea33SDavid du Colombier 	"CR3",
244e887ea33SDavid du Colombier 	"CR4",
245e887ea33SDavid du Colombier 	"CR5",
246e887ea33SDavid du Colombier 	"CR6",
247e887ea33SDavid du Colombier 	"CR7",
248e887ea33SDavid du Colombier 	"CR8",
249e887ea33SDavid du Colombier 	"CR9",
250e887ea33SDavid du Colombier 	"CR10",
251e887ea33SDavid du Colombier 	"CR11",
252e887ea33SDavid du Colombier 	"CR12",
253e887ea33SDavid du Colombier 	"CR13",
254e887ea33SDavid du Colombier 	"CR14",
255e887ea33SDavid du Colombier 	"CR15",
256e887ea33SDavid du Colombier 
257e887ea33SDavid du Colombier 	"DR0",		/* [D_DR] */
258e887ea33SDavid du Colombier 	"DR1",
259e887ea33SDavid du Colombier 	"DR2",
260e887ea33SDavid du Colombier 	"DR3",
261e887ea33SDavid du Colombier 	"DR4",
262e887ea33SDavid du Colombier 	"DR5",
263e887ea33SDavid du Colombier 	"DR6",
264e887ea33SDavid du Colombier 	"DR7",
265e887ea33SDavid du Colombier 
266e887ea33SDavid du Colombier 	"TR0",		/* [D_TR] */
267e887ea33SDavid du Colombier 	"TR1",
268e887ea33SDavid du Colombier 	"TR2",
269e887ea33SDavid du Colombier 	"TR3",
270e887ea33SDavid du Colombier 	"TR4",
271e887ea33SDavid du Colombier 	"TR5",
272e887ea33SDavid du Colombier 	"TR6",
273e887ea33SDavid du Colombier 	"TR7",
274e887ea33SDavid du Colombier 
275e887ea33SDavid du Colombier 	"NONE",		/* [D_NONE] */
276e887ea33SDavid du Colombier };
277e887ea33SDavid du Colombier 
278e887ea33SDavid du Colombier int
Rconv(Fmt * fp)279e887ea33SDavid du Colombier Rconv(Fmt *fp)
280e887ea33SDavid du Colombier {
281e887ea33SDavid du Colombier 	char str[20];
282e887ea33SDavid du Colombier 	int r;
283e887ea33SDavid du Colombier 
284e887ea33SDavid du Colombier 	r = va_arg(fp->args, int);
285e887ea33SDavid du Colombier 	if(r >= D_AL && r <= D_NONE)
286*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
287*40d01547SDavid du Colombier 	else if(r >= D_Y0 && r <= D_Y15)
288*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "Y%d", r-D_Y0);
289*40d01547SDavid du Colombier 	else if(r >= D_M0 && r <= D_M7)
290*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "Y%d", r-D_M0);
291e887ea33SDavid du Colombier 	else
292*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "gok(%d)", r);
293e887ea33SDavid du Colombier 
294e887ea33SDavid du Colombier 	return fmtstrcpy(fp, str);
295e887ea33SDavid du Colombier }
296e887ea33SDavid du Colombier 
297e887ea33SDavid du Colombier int
Sconv(Fmt * fp)298e887ea33SDavid du Colombier Sconv(Fmt *fp)
299e887ea33SDavid du Colombier {
300e887ea33SDavid du Colombier 	int i, c;
301e887ea33SDavid du Colombier 	char str[30], *p, *a;
302e887ea33SDavid du Colombier 
303e887ea33SDavid du Colombier 	a = va_arg(fp->args, char*);
304e887ea33SDavid du Colombier 	p = str;
305e887ea33SDavid du Colombier 	for(i=0; i<sizeof(double); i++) {
306e887ea33SDavid du Colombier 		c = a[i] & 0xff;
307e887ea33SDavid du Colombier 		if(c >= 'a' && c <= 'z' ||
308e887ea33SDavid du Colombier 		   c >= 'A' && c <= 'Z' ||
309e887ea33SDavid du Colombier 		   c >= '0' && c <= '9') {
310e887ea33SDavid du Colombier 			*p++ = c;
311e887ea33SDavid du Colombier 			continue;
312e887ea33SDavid du Colombier 		}
313e887ea33SDavid du Colombier 		*p++ = '\\';
314e887ea33SDavid du Colombier 		switch(c) {
315e887ea33SDavid du Colombier 		default:
316e887ea33SDavid du Colombier 			if(c < 040 || c >= 0177)
317e887ea33SDavid du Colombier 				break;	/* not portable */
318e887ea33SDavid du Colombier 			p[-1] = c;
319e887ea33SDavid du Colombier 			continue;
320e887ea33SDavid du Colombier 		case 0:
321e887ea33SDavid du Colombier 			*p++ = 'z';
322e887ea33SDavid du Colombier 			continue;
323e887ea33SDavid du Colombier 		case '\\':
324e887ea33SDavid du Colombier 		case '"':
325e887ea33SDavid du Colombier 			*p++ = c;
326e887ea33SDavid du Colombier 			continue;
327e887ea33SDavid du Colombier 		case '\n':
328e887ea33SDavid du Colombier 			*p++ = 'n';
329e887ea33SDavid du Colombier 			continue;
330e887ea33SDavid du Colombier 		case '\t':
331e887ea33SDavid du Colombier 			*p++ = 't';
332e887ea33SDavid du Colombier 			continue;
333e887ea33SDavid du Colombier 		}
334e887ea33SDavid du Colombier 		*p++ = (c>>6) + '0';
335e887ea33SDavid du Colombier 		*p++ = ((c>>3) & 7) + '0';
336e887ea33SDavid du Colombier 		*p++ = (c & 7) + '0';
337e887ea33SDavid du Colombier 	}
338e887ea33SDavid du Colombier 	*p = 0;
339e887ea33SDavid du Colombier 	return fmtstrcpy(fp, str);
340e887ea33SDavid du Colombier }
341e887ea33SDavid du Colombier 
342e887ea33SDavid du Colombier void
diag(char * fmt,...)343e887ea33SDavid du Colombier diag(char *fmt, ...)
344e887ea33SDavid du Colombier {
345e887ea33SDavid du Colombier 	char buf[STRINGSZ], *tn;
346e887ea33SDavid du Colombier 	va_list arg;
347e887ea33SDavid du Colombier 
348e887ea33SDavid du Colombier 	tn = "??none??";
349e887ea33SDavid du Colombier 	if(curtext != P && curtext->from.sym != S)
350e887ea33SDavid du Colombier 		tn = curtext->from.sym->name;
351e887ea33SDavid du Colombier 	va_start(arg, fmt);
352e887ea33SDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
353e887ea33SDavid du Colombier 	va_end(arg);
354e887ea33SDavid du Colombier 	print("%s: %s\n", tn, buf);
355e887ea33SDavid du Colombier 
356e887ea33SDavid du Colombier 	nerrors++;
357*40d01547SDavid du Colombier 	if(nerrors > 20 && !debug['A']) {
358e887ea33SDavid du Colombier 		print("too many errors\n");
359e887ea33SDavid du Colombier 		errorexit();
360e887ea33SDavid du Colombier 	}
361e887ea33SDavid du Colombier }
362