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