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