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