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